C# MEF对单例模式有什么价值吗?
我正在从事一个MEF项目,以发现使用和实现技术。我发现的第一个阶段是实现一个动态可配置的集中式数据控制器。自定义行为的一种方法是继承我提供的强制执行奇点规则的类。虽然Singleton模式在使用上受到了极大的诽谤,但我可能已经找到了一个实现,可以在某种程度上验证该模式的存在 形势 假设由主机导入的数据控制模块(DataController)旨在根据同级模块的请求向数据库提供公共管道。我只需要一个DataController,要组成一个模块,DataController必须实现IDataController。DataProvider作为基类的实现是完全可选的;然而,从DataProvider派生将需要一些额外的处理 观察结果 收集事实:C# MEF对单例模式有什么价值吗?,c#,singleton,mef,C#,Singleton,Mef,我正在从事一个MEF项目,以发现使用和实现技术。我发现的第一个阶段是实现一个动态可配置的集中式数据控制器。自定义行为的一种方法是继承我提供的强制执行奇点规则的类。虽然Singleton模式在使用上受到了极大的诽谤,但我可能已经找到了一个实现,可以在某种程度上验证该模式的存在 形势 假设由主机导入的数据控制模块(DataController)旨在根据同级模块的请求向数据库提供公共管道。我只需要一个DataController,要组成一个模块,DataController必须实现IDataContr
- 静态类无法实现或 扩展抽象类或 接口。仅此一项事实 消除了静态类的使用 以确保一个 数据控制器
- 实现 单例模式将确保 每个应用程序的奇异存在性 域名。没有限制 数据控制器;允许继承 需要导入的接口和 在主人面前镇定自若
- 给定DataController的派生 标准实施 单例模式可能被证明是正确的 在同样的情况下具有挑战性。这个 建议的数据库提供了 可公开访问的类: IDataController和一个摘要 数据提供者。确保单一 派生DataController的实例, 实施将需要一些时间 偏离规范
// DataLibrary referenced by Host
public interface IDataController
{
IDataController Start();
DbConnection CreateConnection<TDbConnection>(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<TDataController>()
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<DataController>();
}
public SqlConnection CreateConnection(params string[] args)
{
// instance and return new SqlConnection
}
}
//主机引用的数据库
公共接口IDataController
{
IDataController启动();
DbConnection CreateConnection(参数字符串[]args)
其中TDbConnection:DbConnection,IDbConnection;
}
公共抽象类数据提供者
{
//单例实现
私有静态IDataController dcInstance;
受保护的静态IDataController实例
{
获取{return dcInstance;}
}
// ========================
抽象IDataController CreateController();
受保护的IDataController实例控制器()
其中TDataController:IDataController,new()
{
返回新的TDataController();
}
}
//参考数据库
[导出(类型(IDataController))]
公共类DataController:DataProvider、IDataController
{
公共IDataController启动()
{
返回CreateController();
}
受保护的覆盖IDataController CreateController()
{
返回instanceController();
}
公共SqlConnection CreateConnection(参数字符串[]args)
{
//实例并返回新的SqlConnection
}
}
请记住,我一直在研究这个问题——阅读、理论——但还没有完成实现。当我调试任何问题时,很可能会有一些更新
显然,只有DataController模块继承抽象基类DataProvider时,才强制执行此实现。因此,如果开发人员选择从DataProvider派生DataController,我们应该强制执行奇点规则,以避免滥用或误用
综上所述,我很好奇是否有比我所设计的更可接受或更实际的实现。而且,我开始质疑单例模式是否是正确的选择。由于单身模式的存在备受诟病(而且在大多数情况下,这是理所当然的),因此,我应该质疑我的选择
是否有更实际的实现来满足我的要求?
*在这种情况下,这是单例模式的正确实现吗*
这个实现是否真的有助于该模式的存在?除非您有更多的实现代码,来自DataProvider的所有派生类都将共享这些代码,否则您可能只想删除抽象类。这个实现保证了线程的安全性,并且在不使用锁的情况下使用惰性构造。但是,需要.NET4
public interface IDataController
{
DbConnection CreateConnection<TDbConnection>(params string[] args)
where TDbConnection : DbConnection, IDbConnection;
}
[Export(typeof(IDataController))]
public class DataController : IDataController
{
// singleton implementation
private static volatile Lazy<IDataController> _ControllerInstance = new Lazy<IDataController>(() => new DataController());
public static IDataController ControllerInstance
{
get { return _ControllerInstance.Value; }
}
public DbConnection CreateConnection<TDbConnection>(params string[] args)
where TDbConnection : DbConnection, IDbConnection
{
throw new NotImplementedException();
}
}
公共接口IDataController
{
DbConnection CreateConnection(参数字符串[]args)
其中TDbConnection:DbConnection,IDbConnection;
}
[导出(类型(IDataController))]
公共类数据控制器:IDataController
{
//单例实现
私有静态volatile Lazy _ControllerInstance=new Lazy(()=>new DataController());
公共静态IDataController控制器状态
{
获取{return\u ControllerInstance.Value;}
}
公共数据库连接CreateConnection(参数字符串[]args)
其中TDbConnection:DbConnection,IDbConnection
{
抛出新的NotImplementedException();
}
}
如果要强制执行容器中只存在一个类实例的事实,则可以设置“共享”零件创建策略:
[Export(typeof(IDataController))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class DataController : IDataController
{
...
}
导入IDataController
的每个部件都将接收相同的实例。请注意,如果在导入或导出端未指定零件创建策略,则这已经是MEF中的默认行为
您不应该将“singletoness”构建到类中。组件元数据或容器配置的一部分是单例。其他依赖项注入容器遵循相同的方法。例如,在autofac中,您将某些内容声明为单例,如下所示:
builder.Register(c => new DataController())
.As<IDataController>().SingleInstance();
builder.Register(c=>newdatacontroller())
.As().SingleInstance