我的想法是,我有一个包含大量接口的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容器,我不知道哪一个可以做到这一点,或者更接近这个解决方案,谁知道呢?
答案 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)))
);