可以在没有配置的情况下自动注册所有内容(非通用)的IoC容器(程序集到程序集)

时间:2010-12-17 21:10:20

标签: castle-windsor unity-container structuremap ninject autofac

我的想法是,我有一个包含大量接口的Core项目,以及带有实现的数据和服务项目(所有内容都是1对1),例如:

Core { IFooRepo, IBarRepo, IFooService, IBarService}
Data {FooRepo: IFooRepo, BarRepo : IBarRepo}
Service {FooService : IFooService, BarService : IBarService}

所以我想要像

这样的东西
register(Core, Data);
register(Core, Service);

有很多IoC容器,我不知道哪一个可以做到这一点,或者更接近这个解决方案,谁知道呢?

3 个答案:

答案 0 :(得分:4)

您正在谈论自动注册。许多IoC容器支持这一点。

StructureMap http://structuremap.net/structuremap/ScanningAssemblies.htm

Castle Windsor(见文章第2页底部) http://www.code-magazine.com/article.aspx?quickid=0906051

Autofac http://code.google.com/p/autofac/wiki/Scanning

Ninject 看起来你可以通过Kernel.Scan()来做,虽然我找不到文档。 (服务器不可用。) How to use Ninject Conventions extension without referencing Assembly (or Types within it)

最后我看,Unity不支持自动注册,尽管最近发布的版本可能已经改变了。

更新:感谢Mauricio注意到我错误地将所需功能识别为自动布线。更正并更新了链接。

答案 1 :(得分:3)

在Autofac中,实现这一目标的最简单方法是:

var builder = new ContainerBuilder();

var data = typeof(BarRepo).Assembly();
builder.RegisterAssemblyTypes(data).AsImplementedInterfaces();

var service = typeof(BarService).Assembly();
builder.RegisterAssemblyTypes(service).AsImplementedInterfactes();

var container = builder.Build();

现在,这对于来自Core程序集的服务接口没有选择性。如果这真的很重要(可能不应该),那么就按照这些方式改变上述注册:

var core = typeof(IBarRepo).Assembly();

builder.RegisterAssemblyTypes(data)
    .As(t => t.GetInterfaces()
         .Where(i => i.Assembly == core)
         .Select(i => new TypedService(i)));

干杯, 尼克

答案 2 :(得分:1)

Windsor允许您轻松地将类注册为它们公开的接口,或者全部或者有选择地注册。 (see the documentation)。

它对你的场景没有OOTB支持(过滤实现的接口只包括来自特定程序集的那些)但是(对于Windsor中的所有内容),你可以使用一个钩子轻松拥有它。

container.Register(
   AllTypes.FromAssemblyContaining<SomeClass>()
      WithService.Select((type, @base) =>
         type.GetAllInterfaces()
             .Where(i => i.Assembly == yourInterfacesAssembly)))
);