开发者

How to use some providers with the same service?

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?


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜