MEF是否为Singleton模式提供任何价值?
我正在研究一个MEF项目,以发现使用和实现技术。 我的第一个发现阶段是实现动态可配置和集中的数据控制器。 自定义行为的一种方法是inheritance我提供的强制执行奇点规则的类。 虽然Singleton模式在使用中受到很多诽谤,但我可能已经找到了一种可以在某种程度上validation模式存在困难的实现。
情况
假设主机导入的数据控制模块( DataController )旨在根据兄弟模块的请求为数据库提供公共管道。 我只需要一个DataController并组成一个模块,DataController必须实现IDataController。 DataProvider作为基类的实现纯粹是可选的; 但是,从DataProvider派生需要一些额外的处理。
观察
收集事实 :
-
静态类无法实现或扩展抽象类或接口。 仅此事实就消除了使用静态类来确保DataController的单一存在。
-
实现Singleton模式的DataController将确保每个应用程序域的单一存在。 DataController没有限制; 允许inheritance在Host中导入和编写的必需接口。
-
给定DataController的推导,Singleton模式的标准实现可能在同样的情况下具有挑战性。 建议的数据库提供了可公开访问的类:IDataController和抽象的DataProvider。 为了确保派生的DataController的单个实例,实现将需要偏离规范。
解决方案
此时,解决方案似乎很清楚。 DataHandler基类实现Singleton模式。 我并不天真地认为还有其他方法可以做到这一点。 但这是我对如何实现模式的粗略期望:
// DataLibrary referenced by Host public interface IDataController { IDataController Start(); DbConnection CreateConnection(params string[] args) where TDbConnection : DbConnection, IDbConnection; } public abstract class DataProvider { // singleton implementation private static IDataController dcInstance; protected static IDataController Instance { get{ return dcInstance; } } // ======================== abstract IDataController CreateController(); protected IDataController instanceController() where TDataController : IDataController, new() { return new TDataController (); } } // references DataLibrary [Export(typeof(IDataController))] public class DataController : DataProvider, IDataController { public IDataController Start() { return CreateController(); } protected override IDataController CreateController() { return instanceController(); } public SqlConnection CreateConnection(params string[] args) { // instance and return new SqlConnection } }
请记住,我一直在努力 – 阅读,理论化 – 并且还没有完成实施。 在我调试任何问题时,很可能会有一些更新。
显然,只有DataController模块inheritance抽象基类DataProvider时才会强制执行此实现。 因此,如果开发人员选择从DataProvider派生DataController,我们应该强制执行单一性规则以避免滥用或滥用。
所有这一切,我很好奇是否有比我设计的更可接受或实际的实施。 而且,我开始质疑Singleton模式是否是正确的选择。 由于Singleton模式存在很多诽谤(并且,大部分情况下都是如此),因此我应该质疑我的选择。
是否有更实际的实施来满足我的要求? *在这种情况下,这是Singleton模式的正确实现吗?* 这种实现是否真的为模式的存在提供了任何价值?
如果要强制执行容器中只存在一个类的单个实例的事实,那么您只需设置“共享”部件创建策略:
[Export(typeof(IDataController))] [PartCreationPolicy(CreationPolicy.Shared)] public class DataController : IDataController { ... }
然后导入IDataController
每个部分将接收相同的实例。 请注意,如果您在导入或导出端未指定任何部件创建策略,则这已经是MEF中的默认行为。
你不应该在课堂上建立“单身”。 是否是单例是组件元数据的一部分或容器的配置。 其他dependency injection容器遵循相同的方法。 例如,在autofac中,您将某些东西声明为像这样的单例:
builder.Register(c => new DataController()) .As().SingleInstance();
除非你有更多的实现代码,所有来自DataProvider的派生类都会共享,你可能只想取消抽象类。 此实现保证线程安全并使用惰性构造而不使用锁。 但是,需要.NET 4。
public interface IDataController { DbConnection CreateConnection(params string[] args) where TDbConnection : DbConnection, IDbConnection; } [Export(typeof(IDataController))] public class DataController : IDataController { // singleton implementation private static volatile Lazy _ControllerInstance = new Lazy (() => new DataController()); public static IDataController ControllerInstance { get { return _ControllerInstance.Value; } } public DbConnection CreateConnection(params string[] args) where TDbConnection : DbConnection, IDbConnection { throw new NotImplementedException(); } }