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.
精彩评论