我可以全局设置要使用的接口实现吗?
我有一个界面:
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的一些额外文档