MVC Code First 和具有复杂映射的 Ninject 缓存

发布于 2024-12-01 09:00:04 字数 4666 浏览 1 评论 0原文

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

由于 DbContext 已被释放,操作无法完成。

如果我不包含 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);

My IUnitOfWork

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

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

My ICustomerService

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

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

My question is very similar to this one: MVC3 tool using Entity Framework caching issues with Ninject however my mapping is a bit more complex and when I use InRequestScope I get the following error:

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

If I don't include InRequestScope everything works except EF Code First seems to cache my entities and it doesn't match up to the values in the Db.

Here's my ninject mapping I'm using the ninject mvc3 nuget package (without 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);

My IUnitOfWork

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

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

My ICustomerService

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

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

My other services follow a similar patter.

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

My Repository

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

If anyone can help with the Ninject mapping and the correct way to inject classes it would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

药祭#氼 2024-12-08 09:00:04

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

我在 ninject github 站点此处 在 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);

I found the problem, I was using the [Inject] attribute with a FilterAttribute when the attribute was being called it was before my context had been initialised and that producted the dbContext error.

I followed the wiki on the ninject github site here to setup ninject on FilterAttribute. On issue I did have was finding the BindFilter method, this is hidden away Ninject.Web.Mvc.FilterBindingSyntax namespace.

My ninject mappings now look like:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文