单例中依赖注入数据连接的最佳方法

时间:2013-01-17 16:48:12

标签: dependency-injection ef-code-first singleton

我的应用程序中有一些“缓存”对象,它通过依赖注入(Ninject)获得IRepository(自定义存储库模式契约)。这些对象仅使用存储库一次,但它们具有刷新功能,强制所有者自行刷新。它们是单例,只创建一次,ManualResetEvent确保所有请求都被阻止,直到它被加载。

IRepositories 基于EF CodeFirst ,因此只需确保连接已关闭并永久保留对DbContext的引用即可吗?

我已经禁用了代理和延迟加载,所以...可以从缓存对象的根目录到数百个这些缓存的POCO实体的长引用吗?

干杯。

2 个答案:

答案 0 :(得分:2)

我们参考Julie Lerman的评论,  http://msdn.microsoft.com/en-us/magazine/ee532098.aspx?sdmr=JulieLerman 建议是有几个/许多较小的上下文,并且在Web场景的情况下,每个调用创建一个新的上下文。 虽然她在实体框架和AppFabric中写了关于二级缓存的文章。

随着时间的推移,上下文将包含许多对象,性能会相应下降。 我认为这个网站有一些关于EF性能的好建议。 例如生成的视图。 http://msdn.microsoft.com/en-us/data/hh949853

我的个人建议,我不能说是最佳做法,但是从关注绩效的人那里来看,每次通话都是一个小的有限背景,是一个坚实的长期妥协。 使用生成的视图可以使初始加载时间尽可能小。

您可以通过从上下文中删除未使用的对象的方式来管理永久DBContext。或者使用带有事件的缓存库来执行此操作。这不是一项小任务。

我会对您最终选择的解决方案感兴趣。请发帖。

答案 1 :(得分:0)

最后,我找到的最佳解决方案是创建一种新的包装器:

    public class Generator<T> where T : IDisposable
    {
        readonly Func<T> _generate;
        public Generator(Func<T> generate)
        {
            _generate= generate;
        }

        public T Generate()
        {
            return _generate();
        }
    }

以这种方式或多或少地创建一个绑定:

// Dependency Injection bindings declaration section
DI.Bind<Generator<IRepository>>()
  .To(()=> new Generator<IRepository>(()=> DI.Get<IRepository>()));

因此,在需要创建和销毁元素的长期存在的对象中,我可以要求Generator<IRepository>服务,而不是IRepository。因此,每次我需要刷新时,我都会创建一个新的IRepository,而不知道它是如何构建的:

 using (var repository = repositoryGenerator.Generate())
 {
     repository.DoStuff();
 }

到目前为止它的功能就像一个魅力。

实际上,我已将此功能添加到我的DI框架中。我现在可以绑定IAnything以及稍后对Generator的请求,框架将使用这种技术为我提供完全就绪的对象How to create a Func<> delegate programmatically

干杯。