DbContext 已在自定义 RoleProvider 中处置
DbContext has been disposed in custom RoleProvider
我在 CustomRoleProvider
.
中使用 DbContext 时遇到问题
我已将我的绑定设置为:
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
kernel.Bind(typeof(IGenericRepository<>)).To(typeof(GenericRepository<>)).InRequestScope();
kernel.Bind<MyContext>().ToSelf().InRequestScope();
我正在使用这个 NuGet 包 Ninject.MVC5 v3.2.1.0 所以 Ninject 被设置为 MVC 中的主要 DependencyResolver。这就是为什么我能够做到这一点 DependencyResolver.Current.GetService<IGenericRepository<User>>()
.
但出于某种原因,上下文已被处理。
我尝试将此绑定添加到我的设置中:
kernel.Bind<MyContext>().ToSelf().WhenInjectedInto<RoleProvider>();
但这也不管用。我还尝试通过 属性 注入
注入
[Inject]
public IGenericRepository<User> UserRepository { get; set; };
但这只会导致很多其他问题我无法解决(还)。
据我从错误消息中可以看出,问题是由这里触发的。
public abstract class BaseController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
User.IsInRole("Admin"); // calls my CustomRoleProvider
base.OnActionExecuting(filterContext);
}
}
CustomRoleProvider
实施
public class CustomRoleProvider : RoleProvider
{
private readonly IGenericRepository<User> _userRepository;
public CustomRoleProvider()
{
// using Service Locator (anti pattern)
// cause MVC do not support DI in role providers (yet)
_userRepository = DependencyResolver.Current.GetService<IGenericRepository<User>>();
}
public override bool IsUserInRole(string username, string roleName)
{
var user = _userRepository.AsQueryable().Where(x => x.Username == username && x.Role.Name == roleName); // dbcontext is here disposed...
return user.Any();
}
public override string[] GetRolesForUser(string username)
{
var user = _userRepository.AsQueryable().Where(x => x.Username == username).Select(x => x.Role.Name); // dbcontext is here disposed...
return user.ToArray();
}
// omitted...
}
IGenericRepository<T>
实施
public class GenericRepository<T> : IGenericRepository<T>
where T : class
{
private readonly MyContext _context;
private readonly DbSet<T> _dbSet;
public GenericRepository(MyContext context)
{
_context = context;
_dbSet = context.Set<T>();
}
public IQueryable<T> AsQueryable()
{
return _dbSet.AsQueryable();
}
}
错误信息
[InvalidOperationException: The operation cannot be completed because the DbContext has been disposed.]
System.Data.Entity.Internal.InternalContext.CheckContextNotDisposed() +34
System.Data.Entity.Internal.LazyInternalContext.InitializeContext() +30
System.Data.Entity.Internal.InternalContext.Initialize() +21
System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +20
System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() +79
System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext() +21
System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider() +64
System.Linq.Queryable.Where(IQueryable`1 source, Expression`1 predicate) +81
Presentation.Web.Providers.CustomRoleProvider.GetRolesForUser(String username) in ~\Application\Presentation.Web\Providers\CustomRoleProvider.cs:38
System.Web.Security.RolePrincipal.IsInRole(String role) +183
Presentation.Web.Controllers.BaseController.OnActionExecuting(ActionExecutingContext filterContext) in ~\Application\Presentation.Web\Controllers\BaseController.cs:27
...
显然 RoleProvider 的生命周期是 MVC 应用程序的整个生命周期。 (不记得在哪里读到的)
所以必须解决每个方法中的依赖关系:(
public class CustomRoleProvider : RoleProvider
{
public override bool IsUserInRole(string username, string roleName)
{
var userRepository = DependencyResolver.Current.GetService<IGenericRepository<User>>();
var user = userRepository .AsQueryable().Where(x => x.Username == username && x.Role.Name == roleName); // dbcontext is here disposed...
return user.Any();
}
public override string[] GetRolesForUser(string username)
{
var userRepository = DependencyResolver.Current.GetService<IGenericRepository<User>>();
var user = userRepository .AsQueryable().Where(x => x.Username == username).Select(x => x.Role.Name); // dbcontext is here disposed...
return user.ToArray();
}
// omitted...
}
当时不明白为什么这行不通
kernel.Bind<MyContext>().ToSelf().WhenInjectedInto<RoleProvider>();
我什至尝试添加 InSingletonScope
我在 CustomRoleProvider
.
我已将我的绑定设置为:
kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
kernel.Bind(typeof(IGenericRepository<>)).To(typeof(GenericRepository<>)).InRequestScope();
kernel.Bind<MyContext>().ToSelf().InRequestScope();
我正在使用这个 NuGet 包 Ninject.MVC5 v3.2.1.0 所以 Ninject 被设置为 MVC 中的主要 DependencyResolver。这就是为什么我能够做到这一点 DependencyResolver.Current.GetService<IGenericRepository<User>>()
.
但出于某种原因,上下文已被处理。
我尝试将此绑定添加到我的设置中:
kernel.Bind<MyContext>().ToSelf().WhenInjectedInto<RoleProvider>();
但这也不管用。我还尝试通过 属性 注入
注入[Inject]
public IGenericRepository<User> UserRepository { get; set; };
但这只会导致很多其他问题我无法解决(还)。
据我从错误消息中可以看出,问题是由这里触发的。
public abstract class BaseController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
User.IsInRole("Admin"); // calls my CustomRoleProvider
base.OnActionExecuting(filterContext);
}
}
CustomRoleProvider
实施
public class CustomRoleProvider : RoleProvider
{
private readonly IGenericRepository<User> _userRepository;
public CustomRoleProvider()
{
// using Service Locator (anti pattern)
// cause MVC do not support DI in role providers (yet)
_userRepository = DependencyResolver.Current.GetService<IGenericRepository<User>>();
}
public override bool IsUserInRole(string username, string roleName)
{
var user = _userRepository.AsQueryable().Where(x => x.Username == username && x.Role.Name == roleName); // dbcontext is here disposed...
return user.Any();
}
public override string[] GetRolesForUser(string username)
{
var user = _userRepository.AsQueryable().Where(x => x.Username == username).Select(x => x.Role.Name); // dbcontext is here disposed...
return user.ToArray();
}
// omitted...
}
IGenericRepository<T>
实施
public class GenericRepository<T> : IGenericRepository<T>
where T : class
{
private readonly MyContext _context;
private readonly DbSet<T> _dbSet;
public GenericRepository(MyContext context)
{
_context = context;
_dbSet = context.Set<T>();
}
public IQueryable<T> AsQueryable()
{
return _dbSet.AsQueryable();
}
}
错误信息
[InvalidOperationException: The operation cannot be completed because the DbContext has been disposed.]
System.Data.Entity.Internal.InternalContext.CheckContextNotDisposed() +34
System.Data.Entity.Internal.LazyInternalContext.InitializeContext() +30
System.Data.Entity.Internal.InternalContext.Initialize() +21
System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +20
System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() +79
System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext() +21
System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider() +64
System.Linq.Queryable.Where(IQueryable`1 source, Expression`1 predicate) +81
Presentation.Web.Providers.CustomRoleProvider.GetRolesForUser(String username) in ~\Application\Presentation.Web\Providers\CustomRoleProvider.cs:38
System.Web.Security.RolePrincipal.IsInRole(String role) +183
Presentation.Web.Controllers.BaseController.OnActionExecuting(ActionExecutingContext filterContext) in ~\Application\Presentation.Web\Controllers\BaseController.cs:27
...
显然 RoleProvider 的生命周期是 MVC 应用程序的整个生命周期。 (不记得在哪里读到的)
所以必须解决每个方法中的依赖关系:(
public class CustomRoleProvider : RoleProvider
{
public override bool IsUserInRole(string username, string roleName)
{
var userRepository = DependencyResolver.Current.GetService<IGenericRepository<User>>();
var user = userRepository .AsQueryable().Where(x => x.Username == username && x.Role.Name == roleName); // dbcontext is here disposed...
return user.Any();
}
public override string[] GetRolesForUser(string username)
{
var userRepository = DependencyResolver.Current.GetService<IGenericRepository<User>>();
var user = userRepository .AsQueryable().Where(x => x.Username == username).Select(x => x.Role.Name); // dbcontext is here disposed...
return user.ToArray();
}
// omitted...
}
当时不明白为什么这行不通
kernel.Bind<MyContext>().ToSelf().WhenInjectedInto<RoleProvider>();
我什至尝试添加 InSingletonScope