2011-08-25 36 views
2

我的问题很类似这样的:MVC3 tool using Entity Framework caching issues with Ninject但是我的映射是一个比较复杂的,当我使用InRequestScope我收到以下错误:MVC编码第一和Ninject缓存与复杂的映射

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

如果我不包括InRequestScope除EF Code First之外的所有工作似乎都缓存我的实体,并且它与Db中的值不匹配。

这里是我的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(); 
} 

我的UnitOfWork

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

我ICustomerService

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

我的CustomerService

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

回答

4

我发现这个问题,我在使用[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);