我可以全局设置要使用的接口实现吗?

我有一个界面:

public interface IHHSDBUtils { void SetupDB(); bool TableExists(string tableName); . . . 

……有多个实施者:

 public class SQLiteHHSDBUtils : IHHSDBUtils public class SQCEHHSDBUtils : IHHSDBUtils public class FlatfileHHSDBUtils : IHHSDBUtils public class TestHHSDBUtils : IHHSDBUtils 

我希望能够从全局可访问的位置指定要使用的实施者,例如:

 public static class HHSConsts { public static IHHSDBUtils hhsdbutil = SQLiteHHSDBUtils; 

…然后从app中的任何地方调用它:

 private HHSDBUtils hhsdbutils { get; set; } . . . hhsdbutils = new HHSConsts.hhsdbutil; hhsdbutils.SetupDB(); 

这可能吗? 我得到,“’SQLiteHHSDBUtils’是一个’类型’但是像’变量’一样用于上面的hhsdbutil。

你可以通过为每种类型创建一个枚举来做一个穷人工厂实现,并有一个静态工厂方法为你创建类型。 我尽可能接近您当前的代码段。

 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; } } 

你会像这样使用它:

 private IHHSDBUtils hhsdbutils { get; set; } //. . . hhsdbutils = HHSConsts.GetUtils(); hhsdbutils.SetupDB(); 

另一种选择是使用Activator.CreateInstance 。

  const string fulltypename = "Your.Namespace.SQLiteHHSDBUtils"; // or read from config; hhsdbutils = (HHSDBUtils) Activator.CreateInstance(null, fulltypename).Unwrap(); 

确保测试和测量性能,特别是如果您需要经常通过任何这些方法实例化很多类型。

如果您想要更多控制,请使用dependency injection/控制反转框架,如:

  • 统一
  • Ninject
  • CastelWindsor
  • StructureMap

请注意,所有这些框架都带来了强大的function,但也增加了复杂性。 如果您认为必须选择框架,则将可维护性和可学习性作为主要要求。

这是关于DI的一些额外文档