自定义成员资格+ Ninject + InRequestScope =已经处理了ObjectContext实例

rid*_*nsb 3 dependency-injection ninject custom-membershipprovider asp.net-mvc-3 dbcontext

ObjectContext实例已在InRequestScope中处理!

我在网上尝试了几个小时试图解决问题.

ObjectContext实例已被释放,不能再用于需要连接的操作.

我发现了几个文章和帖子中包含了同样的问题这个,这个,这个这个

我尝试了所有方法,但总是发生错误.


上下文

public class BindSolutionContext : DbContext
{
    public DbSet<Project> Projects { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
    public DbSet<Address> Addresses { get; set; }
    public DbSet<ProjectImage> ProjectImages { get; set; }

    public BindSolutionContext()
        : base("name=Data")
    {
        Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BindSolutionContext>());
    }
}
Run Code Online (Sandbox Code Playgroud)

Ninject

kernel.Bind<BindSolutionContext>().ToSelf().InRequestScope();

kernel.Bind<IProjectRepository>().To<ProjectRepository>().InRequestScope();
kernel.Bind<IUserRepository>().To<UserRepository>().InRequestScope();
kernel.Bind<IRoleRepository>().To<RoleRepository>().InRequestScope();
kernel.Bind<IAddressRepository>().To<AddressRepository>().InRequestScope();
kernel.Bind<IProjectImageRepository>().To<ProjectImageRepository>().InRequestScope();
Run Code Online (Sandbox Code Playgroud)

知识库

public class ProjectRepository : IProjectRepository
{
    private readonly BindSolutionContext _context;

    public ProjectRepository(BindSolutionContext context)
    {
        _context = context;
    }

    public IQueryable<Project> Query(params Expression<Func<Project, object>>[] includeProperties)
    {
        return includeProperties.Aggregate<Expression<Func<Project, object>>,
            IQueryable<Project>>(_context.Projects, (current, includeProperty) => current.Include(includeProperty));
    }

    public IQueryable<Project> Query(int pageIndex, int pageSize, params Expression<Func<Project, object>>[] includeProperties)
    {
        return includeProperties.Aggregate<Expression<Func<Project, object>>,
            IQueryable<Project>>(_context.Projects, (current, includeProperty) => current.Include(includeProperty)).OrderBy(p => p.Name).Skip(pageIndex).Take(pageSize);
    }

    //Rest of Implementation
}
Run Code Online (Sandbox Code Playgroud)

对于ProjectImageRepository,AddressRepository,RoleRepository以及UserRepository实现遵循相同的模型!

public class BindUserProvider : MembershipProvider
{
    [Inject]
    public IUserService UserService { get; set; }

    //Rest of implementation
}


public class BindRoleProvider : RoleProvider
{
    private IRoleService _roleServ;
    private IRoleService RoleServ { get { return _roleServ ?? (_roleServ = DependencyResolver.Current.GetService<IRoleService>()); } }

    private IUserService _userServ;
    private IUserService UserServ { get { return _userServ ?? (_userServ = DependencyResolver.Current.GetService<IUserService>()); } }

    //Rest of implementation
}
Run Code Online (Sandbox Code Playgroud)

由于范围是请求,Ninject应该在请求的最后处置对象.但在某些情况下,在完成请求之前会发生处置.

尝试

我不确定问题是否与Custom成员资格有关,但是做了一些测试.如下:

Ninject

kernel.Bind<BindSolutionContext>().ToSelf().InTransientScope();

kernel.Bind<IProjectRepository>().To<ProjectRepository>().InSingletonScope();
kernel.Bind<IUserRepository>().To<UserRepository>().InSingletonScope();
kernel.Bind<IRoleRepository>().To<RoleRepository>().InSingletonScope();
kernel.Bind<IAddressRepository>().To<AddressRepository>().InSingletonScope();
kernel.Bind<IProjectImageRepository>().To<ProjectImageRepository>().InSingletonScope();
Run Code Online (Sandbox Code Playgroud)

所以没有错误了!

但另一个问题出现了!由于repositorycontext单身对象没有更新.

例如,如果我为项目注册了新地址,project.Addresses则不会更新集合!

注意:地址已在数据库中注册,没有任何问题!

Rem*_*oor 5

成员资格和角色提供者的生命周期比请求更长.对象永远不应该依赖于较短的对象(除非在方法执行期间本地创建和销毁),因为它们最终会引用已处置的对象.

由于您希望新的上下文foreach请求避免使用缓存对象,因此您不能将上下文注入存储库,而是使用方法调用从外部传递它,并使用工厂在服务或提供程序中创建它.


归档时间:

查看次数:

1464 次

最近记录:

13 年,3 月 前