在實際專案中,建議將容器初始化、組件註冊、解析介面封裝為**單例工具類別**,避免重複建立容器並統一異常處理。
public sealed class Container
{
private readonly WindsorContainer _windsor;
private readonly IKernel _kernel;
public IKernel Kernel => _kernel;
private static readonly Container _instance = new Container();
public static Container Instance => _instance;
private Container()
{
try
{
// 從 App.config/Web.config 的 區段載入組件註冊
var source = new Castle.Core.Resource.ConfigResource();
var interpreter = new XmlInterpreter(source);
_windsor = new WindsorContainer(interpreter);
_kernel = _windsor.Kernel;
}
catch (Exception ex)
{
// 專案自訂異常處理
TMSExcetionBase.ProcessBizException(ex);
}
}
/// 依服務型別解析
public T Resolve() => (T)_kernel[typeof(T)];
/// 依服務名稱解析
private object Resolve(string key) => _kernel[key];
public void Dispose() => _kernel.Dispose();
}
主組態僅引用子組態檔,達成模組解耦:
<configuration>
<configSections>
<section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
</configSections>
<castle>
<include uri="file://Configuration/TMS.Role.config" />
<include uri="file://Configuration/TMS.UserInfo.config" />
</castle>
</configuration>
<configuration>
<components>
<component id="UserInfo"
service="TMS.Service.IUserInfoService,TMS.Service"
type="TMS.Component.UserInfoComponent,TMS.Component" />
</components>
</configuration>
include 指定的檔案並註冊。public partial class UserList : System.Web.UI.Page
{
// 欄位注入或屬性注入皆可,這裡示範手動解析
private IUserInfoService _userService = Container.Instance.Resolve();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = _userService.InquireAll();
GridView1.DataBind();
}
}
}
執行結果:GridView 正常顯示資料,證明容器成功解析 IUserInfoService 並注入實作 UserInfoComponent。
WindsorContainer,效能最佳。.config 檔。PerWebRequest 或 Transient 生命週期管理。Container 加入 Register 方法支援程式碼式註冊(Fluent API)。IControllerFactory 交由 Windsor 建構 Controller。