简单的注入器从命名空间注册所有服务

我的服务接口具有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个服务夸大一点。 我需要为每项服务添加一行。

如果是这种情况,我会认为你的设计有问题。 您调用服务IUserServiceICountryService这一事实表明您违反了单一责任 , 开放/封闭和接口隔离原则 。 这可能会导致严重的可维护性问题。

对于替代设计,请查看这 两篇文章。 所描述的设计允许更高水平的可维护性,使注册服务变得更加容易,并且使得孩子们应用横切关注点(特别是使用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); } 

您可以修改此代码以批量应用约定和寄存器类型。