.NET Configurable interface implementation
I have an interface and I wish to do a factory pattern to instantiate different implementor of the interface. But I wish to keel the details of which implementor to be instantiated in the config file. I shall like to have it in the fashion of RoleProvider configuration:
<section name="MembershipProvider" type="MyOwn.UserManagement.Providers.MembershipProvider.CustomMembershipProviderConfigurationSection,MyOwn.UserManagement.Providers.MembershipProvider" allowDefinition="MachineToApplication" />
So its kind of an dependency injection technique. Can somebody help me?
Edit:
The actual situation is like this:
I have an interface IDataExchange
and want to implement it with different assemblies for different customers. So I might have two assemblies that have classes implementing IDataExchange
say, DataExchange1
and DataExchange2
. Now when I deploy, depending upon to which customer I am providing it, I shall like to set the details of the assembly (either DataExchange1
or DataExchange2
) in the config file. This will also allow me or any developer to write new assemblies implementing IDataExchange
for any change required, if the instantiation decision is handled automatically.
So how can I do it?
My implementation:
Thanks to all of you. And special thanks to @Pauli Østerø
I have taken cue from your answers and implemented a solution.
In the config file I added the following:
<add key="Exchanger" value="DExchanger.DExchange1, DExchanger.DExchange1"/>
I added a class (to work as a DI container or the abstract factory). The class is DIContainer
containing the following method:
public IDataExchange CreateInstance(string config)
{
var type = Type.GetType(config);
return (IDataExchange)Activator.CreateInstance(type);
}
And while I am instantiating, I write the following:
var config = ConfigurationManager.AppSettings.Get("Exchanger");
DIContainer x = new DIContainer();
var instance = x.CreateInstance(config);
Console.Write("Provide your input please: ");
string inp=Console.ReadLine();
Console.WriteLine(instance.DoDataExchange(inp));
Console.ReadLin开发者_开发知识库e();
And this is giving me the result I was looking for.
I shall request all of you to put your feedback for further improvement.
Add a property to your CustomMembershipProviderConfigurationSection
named Type
so you can configure it like this in your config file
<group>
<MembershipProvider type="... my concrete type" />
</group>
On your CustomMembershipProviderConfigurationSection
you create a method named CreateInstance
that returns IDataExchange
. The body of the method is pretty simple
public IDataExchange CreateInstance()
{
var type = Type.GetType(this.Type);
return (IDataExchange)Activator.CreateInstance(type);
}
and when you need an IDataExchange
reference you write
var config = (CustomMembershipProviderConfigurationSection)ConfigurationManager.GetSection("group/MembershipProvider");
var instance = config.CreateInstance();
Most Dependency Injection Containers will be able to do what you ask for through their support for XML configuration.
Some common DI Containers are:
- Castle Windsor
- StructureMap
- Unity
- Autofac
- Spring.NET
You should take a look at MEF. Clickity click
It should do exactly what you are looking for.
精彩评论