如何通过使用它的名称作为字符串来动态解析 IoC

How to resolve IoC dynamically by using it's name as string

我对同一个接口有多个实现,如下例

container.Register(Component.For<OrganizationServiceCore.IOrganizationService>().ImplementedBy<SchoolServiceCore.SchoolsProvider.SchoolService>());

 container.Register(Component.For<OrganizationServiceCore.IOrganizationService>().ImplementedBy<CompanyServiceCore.CompanyProvider.CompanyService>());

解析必须依赖于数据库中的值,我将从数据库中以字符串形式获取值 "SchoolServiceCore.SchoolsProvider.SchoolService" 或 "CompanyServiceCore.CompanyProvider.CompanyService"

我如何像下面的例子那样使用它:

string serviceName= "CompanyServiceCore.CompanyProvider.CompanyService";

 container.Register(Component.For<OrganizationServiceCore.IOrganizationService>().ImplementedBy<serviceName>());

您可以尝试使用

string serviceName= "CompanyServiceCore.CompanyProvider.CompanyService";
Type myType= Type.GetType(serviceName);
container.Register(Component.For<OrganizationServiceCore.IOrganizationService>().ImplementedBy<myType>());

并使用它在 IoC 容器中注册您的类型。

根据提供的示例代码,我假设您正在使用 温莎城堡 作为您的 DI 容器。

我至少可以看到两个不同的选项:
1) 全部注册并只使用合适的

container.Register(
   Component.For<OrganizationServiceCore.IOrganizationService>()
     .ImplementedBy<SchoolServiceCore.SchoolsProvider.SchoolService>(),
   Component.For<OrganizationServiceCore.IOrganizationService>()
     .ImplementedBy<CompanyServiceCore.CompanyProvider.CompanyService>());

在这种情况下,第一个获胜。但是,如果您在服务注册期间也调用了 Named 构建器函数,那么您可以通过其名称解析适当的函数。

container.Register(
   Component.For<OrganizationServiceCore.IOrganizationService>()
     .Named("SchoolService")
     .ImplementedBy<SchoolServiceCore.SchoolsProvider.SchoolService>(),
   Component.For<OrganizationServiceCore.IOrganizationService>()
     .Named("CompanyService")
     .ImplementedBy<CompanyServiceCore.CompanyProvider.CompanyService>());

...

 IOrganizationService svc = container.Resolve<IOrganizationService>("SchoolService");

2) 只注册需要的那个
在这种情况下,您应该使用 UsingFactoryMethod 构建器函数来委托相应服务实现的创建过程。

 container.Register(
     Component.For<OrganizationServiceCore.IOrganizationService>()
        .UsingFactoryMethod(
          () => OrganizationServiceFactory.CreateService(serviceNameSetting)));

比较

  • 第一种方法允许同时使用多个实现 时间
  • 第一种方法选择合适的实现 使用方面(这就是所谓的服务定位器模式,它 如果你已经使用 DI,应该尽可能避免)
  • 第二种方法只注册一个实现
  • 第二种方法将注册逻辑与类型推导逻辑分开

欲了解更多信息,请访问 Windsor documentation

     var assemblyName = "CompanyServiceCore.CompanyProvider";
     var serviceName = "CompanyService";
        System.Reflection.Assembly assembly = System.Reflection.Assembly.Load(assemblyName);

     var service = assembly.GetTypes().Where(p =>
                                     p.FullName == assemblyName+"."+serviceName
                                ).FirstOrDefault();

        container.Register(Component.For<OrganizationServiceCore.IOrganizationService>().ImplementedBy(service));

您可以根据需要更改 assemblyName 和 serviceName 变量。

不要忘记在要使用的地方添加项目引用。