Ninject 缓存注入的 DataContext?生命周期管理? [英] Ninject caching an injected DataContext? Lifecycle Management?

查看:18
本文介绍了Ninject 缓存注入的 DataContext?生命周期管理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的存储库中出现了一系列非常奇怪的错误.未找到或更改行,2 个更新中的 1 个失败......没有任何意义.

I had a series of very bizarre errors being thrown in my repositories. Row not found or changed, 1 of 2 updates failed... Nothing made sense.

就好像我的 DataContext 实例被缓存了一样......没有任何意义,我正在考虑转行.

It was as if my DataContext instance was being cached... Nothing made sense and I was considering a career move.

然后我注意到 DataContext 实例是使用依赖注入传入的,使用的是 Ninject(这是我第一次使用 DI...).我删除了依赖注入,一切都恢复了正常.立即.

I then noticed that the DataContext instance was passed in using dependency injection, using Ninject (this is the first time I have used DI...). I ripped out the Dependency Injection, and all went back to normal. Instantly.

所以依赖注入是问题所在,但我仍然不知道为什么.我推测 Ninject 正在缓存注入的 DataContext.

So dependency injection was the issue, but I still don't know why. I am speculating that Ninject was caching the injected DataContext.

这是正确的吗?

Ninject 绑定如下:

The Ninject binding is as follows:

Bind<IPupilBlockService>().To<SqlPupilBlockService>()
   .WithConstructorArgument("db", new dbDataContext());

推荐答案

对于任何生命周期必须显式管理的对象(例如实现 IDisposable 的对象)或对用户很重要的对象,尽量不要注入它们,而是注入一个允许创建此类对象的工厂.例如定义这个接口:

For any object which lifetime must explicitly managed (such as objects that implement IDisposable) or matters to the user, try not to inject them, but inject a factory that allows creating such objects instead. Define this interface for instance:

public interface IDbDataContextFactory
{
    dbDataContext CreateNew();
}

并按如下方式使用它:

public class SqlPupilBlockService
{
    private IDbDataContextFactory contextFactory;

    public SqlPupilBlockService(
        IDbDataContextFactory contextFactory)
    {
        this.contextFactory = contextFactory;
    }

    public void DoSomeOperation()
    {
        using (var db = this.contextFactory.CreateNew())
        {
           // use the dbDataContext here.
        }
    }
}

的实现将非常简单,如下所示:

An implementation of would be very simple, like this:

public class DbDataContextFactory : IDbDataContextFactory
{
    public dbDataContext CreateNew()
    {
        return new dbDataContext();
    }
}

注册是这样的:

Bind<IDbDataContextFactory>().To<DbDataContextFactory>();

工厂的使用使得谁是所创建对象的所有者以及谁应该控制其生命周期变得非常明确.这使您的代码更具可读性,并遵循最小惊喜原则.

The use of a factory makes it very explicit who is the owner of the created object and who should control its lifetime. This makes your code more readable and follows the principle of least surprise.

更新

自从我提交这个答案已经一年多了.我现在不使用工厂,而是经常注入数据上下文本身,并在每个(Web)请求的基础上注册它.然而;可能需要改变设计应用程序的方式,一如既往:这取决于.请查看这个答案.

More than a year has past since I submitted this answer. Instead of using factories, I now often inject the data context itself, and register it on a per (web) request basis. However; a shift in how you need to design your application might be needed, so as always: it depends. Please take a look at this answer.

这篇关于Ninject 缓存注入的 DataContext?生命周期管理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆