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