Can I globally set the interface implementation to use?

廉价感情. 提交于 2019-12-08 03:56:53

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!