问题
I have an interface:
public interface IHHSDBUtils
{
void SetupDB();
bool TableExists(string tableName);
. . .
...that has multiple implementers:
public class SQLiteHHSDBUtils : IHHSDBUtils
public class SQCEHHSDBUtils : IHHSDBUtils
public class FlatfileHHSDBUtils : IHHSDBUtils
public class TestHHSDBUtils : IHHSDBUtils
I want to be able to specify which implementer is going to be used from a globally accessible spot, such as:
public static class HHSConsts
{
public static IHHSDBUtils hhsdbutil = SQLiteHHSDBUtils;
...and then call it like so from anywhere in the app:
private HHSDBUtils hhsdbutils { get; set; }
. . .
hhsdbutils = new HHSConsts.hhsdbutil;
hhsdbutils.SetupDB();
Is this possible? I get, "'SQLiteHHSDBUtils' is a 'type' but is used like a 'variable' with its assignment to hhsdbutil above.
回答1:
You could do a poormans Factory implementation by creating an enum for each type and have a static factory method that creates the type for you. I stay as close to your current code snippets as possible.
public enum HHSDBUtilsTypes
{
Sqllite,
SQCE,
Flatfile,
Test
}
public static class HHSConsts
{
private const string implementation = HHSDBUtilsTypes.Sqllite; // you might read this from the config file
public static IHHSDBUtils GetUtils()
{
IHHSDBUtils impl;
switch(implementation)
{
case HHSDBUtilsTypes.Sqllite:
impl = new SQLiteHHSDBUtils();
break;
case HHSDBUtilsTypes.SQCE:
impl = new SQCEHHSDBUtils();
break;
case HHSDBUtilsTypes.Sqllite:
impl = new FlatfileHHSDBUtils();
break;
default:
impl = new TestHHSDBUtils();
break;
}
return impl;
}
}
And you would use it like so:
private IHHSDBUtils hhsdbutils { get; set; }
//. . .
hhsdbutils = HHSConsts.GetUtils();
hhsdbutils.SetupDB();
An other option is to use Activator.CreateInstance.
const string fulltypename = "Your.Namespace.SQLiteHHSDBUtils"; // or read from config;
hhsdbutils = (HHSDBUtils) Activator.CreateInstance(null, fulltypename).Unwrap();
Make sure to test and measure performance, specially if you need to instantiate a lot of types often via any of these methods.
If you want more control use a Dependency Injection/Inversion of Control framework like:
- Unity
- Ninject
- CastelWindsor
- StructureMap
Be aware though that all of these frameworks bring in their own powerfull features but also added complexity. If you feel you have to select a framework take maintainability and learnability as a dominant requirement.
Here is some extra documentation on DI
来源:https://stackoverflow.com/questions/27236107/can-i-globally-set-the-interface-implementation-to-use