C# 如何使用具有相同服务的某些提供商?

C# 如何使用具有相同服务的某些提供商?,c#,architecture,ioc-container,C#,Architecture,Ioc Container,我使用一些IoC工具(例如StructreMap)注册服务和提供商 现在我有了另一个提供者 public class Provider2 : IProvider { public void Load(int id) {...} } 我想注册该提供者(Provider2),并从IoC工具获取Provider2的服务实例。我能看到的唯一方法是创建Service2,它将从IService2继承,最后一个将从IService继承。现在我可以得到IService2类型的实例,它将用Provide

我使用一些IoC工具(例如StructreMap)注册服务和提供商

现在我有了另一个提供者

public class Provider2 : IProvider
{
    public void Load(int id) {...}
}
我想注册该提供者(Provider2),并从IoC工具获取Provider2的服务实例。我能看到的唯一方法是创建Service2,它将从IService2继承,最后一个将从IService继承。现在我可以得到IService2类型的实例,它将用Provider2启动提供者

public interface IService2 : IService
{ }
public class Service2 : IService2
{
    public Service2(IProvider2 provider) { }
    public void Load(int id) { provider.Load(id); }
}

我的问题是:对于每个新的提供者,我需要为服务编写新的类,即使服务的功能应该保持不变?

不,您不需要这样做

我建议您实现一个抽象工厂模式,以便根据运行时已知的值来选择提供者的正确实现

有关示例,请参见此处:

它在MVC上下文中,但可以在其他场景中轻松实现

示例:

您可以这样注册您的服务(伪代码):

并设置StructureMap以解析与抽象工厂的依赖关系,如下所示:

x.For<IProviderFactory>.Use(new ProviderFactory(this));

这应该行得通。

它不应该是公共服务2(IProvider提供者)?那么你想达到什么目的呢?您想要两个具有相同接口的服务吗?只需要不同的实现->不同的提供程序?我想要两个具有相同实现但不同的提供程序实现的服务。它将接收的提供者和其他时间提供者2。但是,我不会手动调用它。我需要IoCI的服务,但我看不出问题所在。否则,必须让第二个服务解析IProvider。每一个国际奥委会都有一个选择,可以在某些基础上以不同的方式解决接口问题。类似于
YourIoc.Resolve(someParameter)
我尝试了类似于
For().Use().Named(“core”);For().Use().Named(“核心”);For().Use().Named(“gen”);For().Use().Named(“gen”)var o=ObjectFactory.GetNamedInstance(“核心”)获取服务时;var o2=ObjectFactory.GetNamedInstance(“gen”)在这两种情况下都可以将IProvider实例化为Provider2,为什么?您应该只注册一次IServiceProvider映射。我发布了一些代码
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;     
    }     
    ...
}
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
    }
}