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

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

问题描述

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



好像我的DataContext实例正在被缓存...没有什么有意义的,我正在考虑职业生涯。



然后我注意到DataContext实例使用依赖注入传递,使用Ninject(这是我第一次使用DI ...)。我撕掉了依赖注射,全部恢复正常。即时。



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



这是否正确?



编辑:



Ninject绑定如下:

 绑定< IPupilBlockService>()。到< SqlPupilBlockService>()
.WithConstructorArgument(db,new dbDataContext());


解决方案

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

  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())
{
/ /这里使用dbDataContext。
}
}
}

简单,像这样:

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

注册如下:

 绑定< IDbDataContextFactory>()。到< DbDataContextFactory>(); 

使用工厂使其非常明确谁是创建对象的所有者,谁应该控制它的一生。这使您的代码更易读,并遵循最不重要的原则



更新



自提交此答案以来,已有一年多了。而不是使用工厂,我现在经常注入数据上下文本身,并以一个(Web)请求的形式注册。然而;可能需要改变您需要设计应用程序的方式,因此一直依赖于它。请查看此答案


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.

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

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.

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

Is this correct?

Edit:

The Ninject binding is as follows:

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

解决方案

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();
}

And use it as follows:

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();
    }
}

And registration goes like this:

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.

UPDATE

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天全站免登陆