如何使用具有相同服务的某些提供商
本文关键字:提供商 服务 何使用 | 更新日期: 2023-09-27 18:00:34
我注册服务&提供一些IoC工具(例如StructeMap)
public interface IProvider
{
void Load(int id);
}
public class Provider : IProvider
{
public void Load(int id) {...}
}
public interface IService
{
void Load(int id);
}
public class Service : IService
{
public Service(IProvider provider) { }
public void Load(int id) { provider.Load(id); }
}
现在我有另一个供应商
public class Provider2 : IProvider
{
public void Load(int id) {...}
}
我想注册那个提供者(Provider2),并从IoC工具中获得带有Provider2的Service实例。我能看到的唯一方法是创建将从IService2继承的Service2,最后一个将从IService继承。现在,我可以获得IService2类型的实例,该实例将使用Provider2启动提供程序。
public interface IService2 : IService
{ }
public class Service2 : IService2
{
public Service2(IProvider2 provider) { }
public void Load(int id) { provider.Load(id); }
}
我的问题是:对于每一个新的提供者,我都需要为服务编写新的类,即使服务的功能应该保持不变?
不,您不需要这么做。
我建议您实现一个抽象的工厂模式,根据运行时已知的值来选择提供者的正确实现。
例如,请查看此处:http://alsagile.com/archive/2010/06/28/Abstract-Factory-and-IoC-Container-in-asp-net-MVC.aspx.
它在MVC上下文中,但可以在其他场景中轻松实现。
示例:
你可以这样注册你的服务(伪代码):
x.For<IService>().Use<Service>();
x.For<IProvider>().Use<Provider1>().Named("provider1");
x.For<IProvider>().Use<Provider2>().Named("provider2");
您需要一种方法在抽象工厂中注入容器。你可以这样包装它:
public interface IProviderFactory
{
object GetInstance<IProvider>();
object GetNamedInstance<IProvider>(string key);
}
以及实现:
public class ProviderFactory : IProviderFactory
{
private readonly Container _container
public ProviderFactory (Container container)
{
_container = container;
}
...
}
并设置StructureMap来解决对抽象工厂的依赖关系,如下所示:
x.For<IProviderFactory>.Use(new ProviderFactory(this));
然后,在您的服务中,您应该像这个一样注入提供商工厂
public class Service : IService
{
private readonly IProviderFactory _providerFactory;
public Service(IProviderFactory factory)
{
if (factory == null)
throw new ArgumentNullException("factory", "providerfactory cannot be null");
_proiderFactory = factory;
}
public void Load(string providerName)
{
var provider = _providerFactory.GetNamedInstance(providerName);
// do some operation on provider
}
}
这应该行得通。