使用 EF 的单例设计模式和异步方法

Singleton design pattern and asynchrounous method with EF

我有一个 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),而不是在每个方法中创建和处理它。

我想知道这是否是个好主意?如果存在另一种可以改进代码的方法,我愿意接受建议

单例模式用于拒绝创建多个实例。 作为此模式的一个可以容忍的缺点,它创建了一个全局变量。这就是您为使用它所付出的代价。

你似乎是那些想要全局变量的人之一,读过全局变量是 "bad" (tm) 现在他们发现了单例模式,虽然他们不需要它的优势,但他们会很乐意为此付出代价,因为现在你有借口拥有一个全局变量:但这是一种模式!

别这样了。模式本身并不好。它们是解决问题的工具。你没有问题,所以不要通过应用随机工具来修复它!

找到您的问题,然后然后寻找规律。提示:在 99% 的情况下,Singleton 不会很好地解决你的问题。即使看起来是这样,我向您保证使用 "singleton" 生命周期变量的依赖注入会好很多。

在您的情况下,传递给所有函数的单个变量可能就足够了。

正如@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");
}