Dependency injection Ninject缓存注入的DataContext?生命周期管理?

Dependency injection Ninject缓存注入的DataContext?生命周期管理?,dependency-injection,datacontext,ninject,lifecycle,Dependency Injection,Datacontext,Ninject,Lifecycle,我的存储库中抛出了一系列非常奇怪的错误。未找到或更改行,2个更新中的1个更新失败。。。什么都说不通 好像我的DataContext实例正在被缓存。。。什么都说不通,我正在考虑转行 然后我注意到DataContext实例是使用依赖项注入和Ninject传入的(这是我第一次使用DI…)。我撕掉了依赖注入,一切都恢复了正常。马上 所以依赖注入是个问题,但我仍然不知道为什么。我推测Ninject正在缓存注入的DataContext 这是正确的吗 编辑: Ninject绑定如下所示: Bind<IP

我的存储库中抛出了一系列非常奇怪的错误。未找到或更改行,2个更新中的1个更新失败。。。什么都说不通

好像我的DataContext实例正在被缓存。。。什么都说不通,我正在考虑转行

然后我注意到DataContext实例是使用依赖项注入和Ninject传入的(这是我第一次使用DI…)。我撕掉了依赖注入,一切都恢复了正常。马上

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

这是正确的吗

编辑: Ninject绑定如下所示:

Bind<IPupilBlockService>().To<SqlPupilBlockService>()
   .WithConstructorArgument("db", new dbDataContext());
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.
        }
    }
}
Bind().To())
.WithConstructorArgument(“db”,新的dbDataContext());
看一看。您的DataContext可能被绑定在一个单例作用域中,或者其他作用域之一,这将导致根据您的调用上下文从内核返回相同的实例


(我对ninject不太熟悉,但默认情况下是暂时作用域,我希望在应用程序代码中的某个地方DataContext被明确定义为具有非暂时作用域)

对于任何生命周期必须明确管理的对象(例如实现
IDisposable
)或对用户重要的对象,尝试不注入它们,而是注入允许创建此类对象的工厂。定义此接口,例如:

public interface IDbDataContextFactory
{
    dbDataContext CreateNew();
}
并按如下方式使用:

Bind<IPupilBlockService>().To<SqlPupilBlockService>()
   .WithConstructorArgument("db", new dbDataContext());
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.
        }
    }
}
的实现将非常简单,如下所示:

public class DbDataContextFactory : IDbDataContextFactory
{
    public dbDataContext CreateNew()
    {
        return new dbDataContext();
    }
}
Bind<IDbDataContextFactory>().To<DbDataContextFactory>();
注册是这样的:

public class DbDataContextFactory : IDbDataContextFactory
{
    public dbDataContext CreateNew()
    {
        return new dbDataContext();
    }
}
Bind<IDbDataContextFactory>().To<DbDataContextFactory>();
Bind().To();
工厂的使用使得谁是所创建对象的所有者以及谁应该控制其生命周期变得非常明确。这使您的代码更具可读性,并遵循以下步骤

更新


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

@Steven给出了很好的解释,但实际上,Ninject已经为您提供了一种方法来指定为每个请求生成一个实例:

Bind()
.至()
.InRequestScope()
.WithConstructorArgument(“db”,新的dbDataContext());

否,我刚刚使用了Ninject默认设置。在这种情况下,我只能认为这实际上取决于IPupilBlockService实现的生命周期和使用它的客户端。爱的原则是最少惊喜!回答得很好,我喜欢这个想法和模式。我将测试它是否解决了我的问题,如果它解决了,你将得到饼干。目前,+1.btw。不科学的研究证明,关于IoC集装箱的所有问题中,有86.3%可以通过使用工厂来解决:-)实现了梦想。清晰地分开关注点。参数在我的控制下。所需的依赖注入最少。我的知识是逐渐增长的,而不是急剧增长的。惊喜是最小化的。我继续前进。圣诞快乐。