asp.net-mvc - MVC Code First 和具有复杂映射的 Ninject 缓存

标签 asp.net-mvc dependency-injection scope ninject code-first

我的问题与此非常相似:MVC3 tool using Entity Framework caching issues with Ninject但是我的映射有点复杂,当我使用 InRequestScope 时,我收到以下错误:

The operation cannot be completed because the DbContext has been disposed.

如果我不包含 InRequestScope ,除了 EF Code First 似乎会缓存我的实体并且它与数据库中的值不匹配之外,一切都会正常工作。

这是我的 ninject 映射,我正在使用 ninject mvc3 nuget 包(没有 InRequestScope):

kernel.Bind<MyContext>()
  .ToSelf()
  .WithConstructorArgument("connectionString", context => MvcApplication.GetConnectionStringName);

kernel.Bind<IUnitOfWork>().To<UnitOfWork>();

// Service Layer.
kernel.Bind<ICustomerService>().To<CustomerService>();
kernel.Bind<IMessageService>().To<MessageService>();
kernel.Bind<IUserService>().To<UserService>();

// Repository Layer.
kernel.Bind<IRepository<Customer>>().To<GenericRepository<Customer>>();
kernel.Bind<IRepository<Message>>().To<GenericRepository<Message>>();
kernel.Bind<IRepository<User>>().To<GenericRepository<User>>();

NinjectContainer.Initialize(kernel);

我的 IUnitOfWork

public interface IUnitOfWork
{
    IUserService UserService { get; }
    ICustomerService CustomerService { get; }
    IMessageService MessageService { get; }
    void CommitChanges();
}

我的工作单元

public class UnitOfWork : IUnitOfWork
{
    MyContext _context;

    private readonly IUserService _userService;
    private readonly ICustomerService _customerService;
    private IMessageService _messageService;

    public UnitOfWork(IUserService userService,
        ICustomerService customerService,
        IMessageService messageService,
        MyContext context)
    {
        _userService = userService;
        _customerService = customerService;
        _messageService = messageService;

        SetContext(optimaContext);
    }

    private void SetContext(MyContext context)
    {
        _context = context;
        _userService.Context = _context;
        _customerService.Context = _context;
        _messageService.Context = _context;
    }
    public void CommitChanges()
    {
        _context.SaveChanges();
    }

    public IUserService UserService { get { return _userService; } }
    public ICustomerService CustomerService { get { return _customerService; } }
    public IMessageService MessageService { get { return _messageService; } }
}

我的客户服务

public interface ICustomerService
{
    DbContext Context { get; set; }
    IQueryable<Customer> All();
}

我的客户服务

public class CustomerService : ICustomerService
{
    IRepository<Customer> _customerRepo;

    public CustomerService(IRepository<Customer> customerRepo)
    {
        _customerRepo = customerRepo;
    }

    private DbContext _context;
    public DbContext Context
    {
        get { return _context; }
        set { _context = value; _customerRepo.Context = value; }
    }

    public IQueryable<Customer> All()
    {
        return _customerRepo.All();
    }
}

我的其他服务也遵循类似的模式。

我的IRepository

public interface IRepository<T> where T : class, new()
{
    DbContext Context { get; set; }

    T Single(Expression<Func<T, bool>> expression);
    T Find(object id);
    IQueryable<T> All();
    void Delete(Expression<Func<T, bool>> expression);
    void Delete(T item);
}

我的存储库

public class GenericRepository<T> : IRepository<T> where T : class, new()
{
    DbContext _context;

    public DbContext Context
    {
        get { return _context; }
        set { _context = value; }
    }

    public virtual T Single(Expression<Func<T, bool>> expression)
    {
        return All().FirstOrDefault(expression);
    }

    public virtual T Find(object id)
    {
        return _context.Set<T>().Find(id);
    }

    public virtual IQueryable<T> All()
    {
        return _context.Set<T>();
    }

    public virtual void Delete(Expression<Func<T, bool>> expression)
    {
        var items = All().Where(expression);
        foreach (var item in items)
        {
            Delete(item);
        }
    }

    public virtual void Delete(T item)
    {
        _context.Set<T>().Remove(item);
    }
}

如果有人可以帮助解决 Ninject 映射以及注入(inject)类的正确方法,我们将不胜感激。

最佳答案

我发现了问题,当调用该属性时,我正在将 [Inject] 属性与 FilterAttribute 一起使用,这是在我的上下文初始化并生成之前dbContext 错误。

我关注了 ninject github 站点上的 wiki hereFilterAttribute 上设置 ninject。我确实遇到的问题是找到 BindFilter 方法,该方法隐藏在 Ninject.Web.Mvc.FilterBindingSyntax 命名空间中。

我的 ninject 映射现在看起来像:

kernel.Bind<MyContext>()
  .ToSelf()
  .InRequestScope()
  .WithConstructorArgument("connectionString", context => MvcApplication.GetConnectionStringName);

kernel.Bind<IUnitOfWork>().To<UnitOfWork>();

// Service Layer.
kernel.Bind<ICustomerService>().To<CustomerService>();
kernel.Bind<IMessageService>().To<MessageService>();
kernel.Bind<IUserService>().To<UserService>();

// Repository Layer.
kernel.Bind<IRepository<Customer>>().To<GenericRepository<Customer>>();
kernel.Bind<IRepository<Message>>().To<GenericRepository<Message>>();
kernel.Bind<IRepository<User>>().To<GenericRepository<User>>();

// Attributes
kernel.BindFilter<AuthorizeWithTokenAttribute>(FilterScope.Controller, 0)
            .WhenControllerHas<AuthorizeWithTokenFilter>()
            .WithConstructorArgumentFromControllerAttribute<AuthorizeWithTokenFilter>("roles", attribute => attribute.Roles)
            .WithConstructorArgumentFromControllerAttribute<AuthorizeWithTokenFilter>("users", attribute => attribute.Users);

关于asp.net-mvc - MVC Code First 和具有复杂映射的 Ninject 缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7189220/

相关文章:

PHP 回调函数和变量引用

c# - MVC : How to manage slahses in URL int the first route parameter

c++ - 关于我的变量范围需要一些解释

c# - 编辑 razor (cshtml) 文件时没有快速操作吗?

java - 使用 Spring JavaConfig 的 bean 初始化图

methods - 在函数内部定义结构的方法

c# - 使用 AutoFac 根据构造函数参数名传递不同的实例

variables - 错误值在 if 语句之外消失

ASP.net MVC 4 Web Api 路由,其中​​包含文件名

c# - 合并 DBContext 和 IdentityDbContext