我有一个wpf应用程序,其中我使用EF作为ORM。
我有许多异步调用的方法:
public Task<double> GetSelectedOGCAvance2(int reference)
{
return Task.Factory.StartNew(() =>
{
DataEntities _db = new DataEntities();
_db.Configuration.LazyLoadingEnabled = false;
using (_db)
{
var dpcs = _db.ass_dpc_ogc.Where(x => x.ass_dpc_id_fk == reference).ToList();
return (Double)dpcs[0].ass_dpc_ogc_avance2.Value;
}
});
}
上面的方法就是一个例子,所用的所有方法都与它类似。
我想将Singleton Pattern
实施到 DbContext (_db),而不是在每个方法中创建和处理它。
我想知道这是不是一个好主意?如果存在可以改进代码的另一种方式,我愿意接受建议
答案 0 :(得分:3)
Singleton Pattern用于拒绝创建多个实例。 作为此模式的容忍缺点,它会创建一个全局变量。这是你为它使用而付出的代价。
你似乎是那些想要一个全局变量的人之一,已经读过全局变量是&#34;坏&#34; (tm)现在他们发现了单身人士模式,虽然他们不需要它的优点,但他们很乐意付出代价,因为现在你有借口拥有一个全局变量:但它& #39; sa模式!
停止。模式本身并不好。它们是解决问题的工具。你没有问题,所以不要通过应用随机工具来修复它!
找到您的问题,只有然后寻找模式。提示:在99%的情况下,Singleton不是解决问题的好方法。即使它看起来像这样,我保证依赖注入一个变量&#34; singleton&#34;一生会好很多。
在您的情况下,传递给所有函数的单个变量可能就足够了。
答案 1 :(得分:1)
正如@nvoigt所提到的,Singleton很少是一个好主意,你最好使用IoC来控制对象的生命周期。
但是如果你想写一个,好的指南是Jon Skeet的blog on singleton。他的第六个版本的通用版本可能如下所示:
public class Foo {}
public sealed class Singleton<T> where T : class, new()
{
private static readonly Lazy<T> lazy = new Lazy<T>(() => new T());
public static T Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
void Main()
{
Foo foo1 = Singleton<Foo>.Instance;
Foo foo2 = Singleton<Foo>.Instance;
if(foo1 == foo2)
{
Console.WriteLine("Foos are equal");
}
}
我之前没有使用过SimpleIoc
,但根据documentation,您应该可以注册这样的单例实例:
var container = new GalaSoft.MvvmLight.Ioc.SimpleIoc();
var foo = new Foo();
container.Register<Foo>(() => foo);
var foo1 = container.GetInstance<Foo>();
var foo2 = container.GetInstance<Foo>();
if(foo1 == foo2 && foo1 == foo)
{
Console.WriteLine("Foos are equal");
}