【问题标题】:MVC Code first and Ninject caching with complex mappingsMVC 代码优先和具有复杂映射的 Ninject 缓存
【发布时间】:2011-08-25 11:00:36
【问题描述】:

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

操作无法完成,因为 DbContext 已被释放。

如果我不包含 InRequestScope 一切正常,除了 EF Code First 似乎缓存了我的实体并且它与 Db 中的值不匹配。

这是我使用 ninject mvc3 nuget 包的 ninject 映射(不带 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);

我的工作单位

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 映射和注入类的正确方法,将不胜感激。

【问题讨论】:

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


    【解决方案1】:

    我发现了问题,我在使用 [Inject] 属性和 FilterAttribute 时调用该属性是在我的上下文初始化之前并产生了 dbContext 错误。

    我按照 ninject github 站点 here 上的 wiki 在 FilterAttribute 上设置 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 2014-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-27
      相关资源
      最近更新 更多