如何使用一些提供相同服务的提供商?

发布于 2024-11-17 17:31:55 字数 931 浏览 0 评论 0原文

我注册了服务&具有某些 IoC 工具的提供程序(例如 StructreMap)

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 的服务实例。我认为执行此操作的唯一方法是创建将从 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); }
}

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

I register the Service & Provider with some IoC tool(e.g. StructreMap)

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); }
}

Now I have another provider

public class Provider2 : IProvider
{
    public void Load(int id) {...}
}

I want to register that provider(Provider2) and to get the instance of Service with Provider2 from IoC tool. The only way I can see to do this is to create Service2 that will inherit from IService2 and the last will inherit from IService. And now I can get instance of type IService2 that will initiate provider with Provider2.

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

My question is: for every new Provider I need to write new class for Service even if the functionality of the service should remain the same?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

著墨染雨君画夕 2024-11-24 17:31:55

不,你不需要这样做。

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

有关示例,请查看此处: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
    }
}

这应该可以工作。

No, you don't need to do that.

I would advice you to implement an abstract factory pattern for selecting the right implementation of provider depending on the value know at runtime.

For an example please look here : http://alsagile.com/archive/2010/06/28/Abstract-Factory-and-IoC-Container-in-asp-net-MVC.aspx.

It's in MVC context but can be easily implemented in other scenarios.

Example :

Youd could register your service like this (pseudo code) :

x.For<IService>().Use<Service>();    
x.For<IProvider>().Use<Provider1>().Named("provider1");
x.For<IProvider>().Use<Provider2>().Named("provider2");

You need a way to inject the container in your Abstract factory. You could wrapp it for example like this:

public interface IProviderFactory
{    
    object GetInstance<IProvider>();    
    object GetNamedInstance<IProvider>(string key);
}

And the implementation :

public class ProviderFactory : IProviderFactory
{     
    private readonly Container _container     
    public ProviderFactory (Container container)     
    {          
        _container = container;     
    }     
    ...
}

And setup StructureMap to resolve dependencies to your abstract factory like that :

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

Then into your Service you should inject the provider factory like 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
    }
}

This should work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文