如何通过使用它的名称作为字符串来动态解析 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 变量。
不要忘记在要使用的地方添加项目引用。
我对同一个接口有多个实现,如下例
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 变量。
不要忘记在要使用的地方添加项目引用。