Castle Windsor:从一个程序集中自动注册类型,从而实现另一个程序集的接口

时间:2010-11-01 15:35:45

标签: c# castle-windsor ioc-container fluent-interface

我使用Castle Windsor作为我的IoC container。我的应用程序具有类似于以下的结构:

  • MyApp.Services.dll
    • IEmployeeService
    • IContractHoursService
    • ...
  • MyApp.ServicesImpl.dll
    • EmployeeService : MyApp.Services.IEmployeeService
    • ContractHoursService : MyApp.Services.IContractHoursService
    • ...

我现在使用XML configuration,每次添加新的IService / Service对时,我都需要在XML配置文件中添加一个新组件。我想将所有这些切换到fluent registration API,但还没有完全正确正确的配方来做我想做的事。

有人可以帮忙吗?生活方式都是singleton

非常感谢提前。

2 个答案:

答案 0 :(得分:12)

使用AllTypes,您可以轻松完成此操作:

来自http://stw.castleproject.org/(S(nppam045y0sdncmbazr1ob55))/Windsor.Registering-components-by-conventions.ashx

  

逐个注册组件可能是非常重复的工作。还记得注册你添加的每个新类型很快就会导致沮丧。幸运的是,至少你总是不必这样做。通过使用AllTypes条目类,您可以根据您指定的某些指定特征执行类型的组注册。

我认为您的注册状态如下:

AllTypes.FromAssembly(typeof(EmployeeService).Assembly)
    .BasedOn<IEmployeeService>()
    .LifeStyle.Singleton

如果在接口上实现基类型,如IService,则可以使用以下构造一次注册它们:

AllTypes.FromAssembly(typeof(EmployeeService).Assembly)
    .BasedOn<IService>()
    .WithService.FromInterface()
    .LifeStyle.Singleton

有关更多示例,请参阅文章。这对可能性有很好的描述。

答案 1 :(得分:4)

我向Pieter's answer前进了一点点(正如他所建议的那样,关键是AllTypes)并提出了这个问题:

// Windsor 2.x
container.Register(
    AllTypes.FromAssemblyNamed("MyApp.ServicesImpl")
    .Where(type => type.IsPublic)
    .WithService.FirstInterface()
    );

这将遍历MyApp.ServicesImpl.dll程序集中的所有公共类,并使用它实现的第一个接口在容器中注册每个类。因为我想要服务程序集中的所有类,所以我不需要标记接口。

以上适用于旧版Windsor。最新版本的当前Castle Windsor documentation for registering components表明以下内容:

// Windsor latest
container.Register(
    AllTypes.FromAssemblyNamed("MyApp.ServicesImpl")
    .Where(type => type.IsPublic) // Filtering on public isn't really necessary (see comments) but you could put additional filtering here
    .WithService.DefaultInterface()
    );