简单的注入器从命名空间注册所有服务
我的服务接口具有Services.Interfaces
的命名空间
Service Interfaces的实现具有Web.UI.Services
的命名空间
例如,我有2个服务实现
- 需要注册到UserService的IUserService
- ICountryService需要注册到CountryService
这就是我目前使用SimpleInjector注册这些服务的方法。
container.Register (); container.Register ();
问题:如果我有超过100个服务夸大了一点。 我需要为每项服务添加一行。
如何使用Simple Injector将所有实现从一个程序集注册到所有接口形成另一个程序集?
您可以通过使用LINQ和reflection查询程序集并注册所有类型来执行此操作:
var registrations = from type in typeof(UserService).Assembly.GetExportedTypes() where type.Namespace.StartsWith("Services.Interfaces") where type.GetInterfaces().Any() select new { Service = type.GetInterfaces().Single(), Implementation = type }; foreach (var reg in registrations) { container.Register(reg.Service, reg.Implementation); }
这在这里描述。
如果我有超过100个服务夸大一点。 我需要为每项服务添加一行。
如果是这种情况,我会认为你的设计有问题。 您调用服务IUserService
和ICountryService
这一事实表明您违反了单一责任 , 开放/封闭和接口隔离原则 。 这可能会导致严重的可维护性问题。
对于替代设计,请查看这 两篇文章。 所描述的设计允许更高水平的可维护性,使注册服务变得更加容易,并且使得孩子们应用横切关注点(特别是使用Simple Injector)。
您正在寻找“约定优于配置”。 简单的进样器调用此批处理/自动注册 。
虽然主要的DI容器为此提供API,但似乎Simple Injector将它留给我们; 通过reflection和LINQ,可以将类型注册为批处理,因此Simple Injector不为此提供特殊的API。
想法是你用一些约定扫描程序集中的具体类型,看看它是否实现了任何接口; 如果是,请注册。
这是从上面链接中提取的样本:
var repositoryAssembly = typeof(SqlUserRepository).Assembly; var registrations = from type in repositoryAssembly.GetExportedTypes() where type.Namespace == "MyComp.MyProd.BL.SqlRepositories" where type.GetInterfaces().Any() select new { Service = type.GetInterfaces().Single(), Implementation = type }; foreach (var reg in registrations) { container.Register(reg.Service, reg.Implementation, Lifestyle.Transient); }
您可以修改此代码以批量应用约定和寄存器类型。