掌握使用 NBearV3 IoC 模組開發單機/分散式應用的完整流程,理解分散式系統中實體定義與服務介面設計的關鍵注意事項。
NBearV3 分散式支援基於 ServiceMQ Server 訊息中心,使用 .NET Remoting 傳遞訊息,Castle Windsor 作為 IoC 容器。用戶端透過定義本地服務介面與實作、配置部署,即可在不修改程式碼甚至不重新編譯情況下賦予應用分散式能力,支援以 Service 為單位多伺服器部署與自動負載平衡。
dist 目錄 DLL/EXE 與 tutorials\IoC_Tutorial 基礎專案Category 與 Product 互相參考(Category.Products、Product.Category)。分散式呼叫時參數/回傳值會序列化傳遞,導致無限遞迴:Product → Category → Products → Product...。
[MappingName("Categories")]
public interface Category : Entity {
[PrimaryKey] int CategoryID { get; }
string CategoryName { get; set; }
string Description { get; set; }
byte[] Picture { get; set; }
[FkQuery("Category", OrderBy = "{ProductName}", Contained = true, LazyLoad = true)]
[SerializationIgnore] // 關鍵:忽略序列化
Product[] Products { get; set; }
}
將 Category.Products 設為 [SerializationIgnore] 或唯讀(只有 get),即可打破循環。
NBear.Tools.EntityDesignToEntity.exe 載入 DLLIoC_Adv_Tutorial\Bin\
├─ ServiceMQServer\ (NBear.IoC.Servers.ServiceMQServer.exe + 相關 DLL)
└─ ServiceHost\ (ServiceHost.exe + 服務介面/實作/實體 DLL + 相關 DLL)
<configuration>
<configSections>
<section name="serviceFactory" type="NBear.IoC.Service.Configuration.ServiceFactoryConfigurationSection, NBear.IoC" />
</configSections>
<serviceFactory type="Remoting" name="testServiceFactory" protocol="HTTP" server="127.0.0.1" port="8888" debug="true" maxTry="30" />
</configuration>
關鍵:type="Remoting" 啟用遠端連線,預設 Local 無法連線遠端。
<configuration>
<configSections> ... </configSections>
<entityConfig> <includes> <add key="Sample Entity Config" value="~/EntityConfig.xml" /> </includes> </entityConfig>
<castle>
<components>
<component id="category service" service="ServiceInterfaces.ICategoryService, ServiceInterfaces" type="ServiceImpls.CategoryService, ServiceImpls" />
<component id="product service" service="ServiceInterfaces.IProductService, ServiceInterfaces" type="ServiceImpls.ProductService, ServiceImpls" />
</components>
</castle>
<serviceFactory type="Remoting" name="testServiceFactory" protocol="HTTP" server="127.0.0.1" port="8888" debug="true" maxTry="30" />
<connectionStrings> ... </connectionStrings>
</configuration>
ServiceHost 需完整配置實體、Castle 元件、連線字串,因其需直接存取資料庫執行服務邏輯。
<castle>
<components>
<component id="category service" service="ServiceInterfaces.ICategoryService, ServiceInterfaces" type="ServiceImpls.CategoryService, ServiceImpls" />
<!-- 保留本地 category service,移除 product service 強制走遠端 -->
</components>
</castle>
<serviceFactory type="Remoting" name="testServiceFactory" protocol="HTTP" server="127.0.0.1" port="8888" debug="true" maxTry="30" />
ServiceMQServer.exeServiceHost.exe 實例(觀察訂閱日誌)實體序列化時已觸發屬性存取,遠端接收的實體 LazyLoad 屬性實際已載入,存取時直接回傳記憶體資料。
System.Reflection.Emit 動態建立代理類別(快取復用)SerializationManager.RegisterSerializeHandler() 註冊特定型別自訂序列化/反序列化