我有一个继承RoleProvider的自定义SiteRole类。我在构造函数中注入IUserService,以便进行查询以获取所有角色。
它继续抛出一个错误,SiteRole类需要一个无参数构造函数。所以我最终注入了IUserService:
public SiteRole()
{
_userService = DependencyResolver.Current.GetService<IUserService>();
}
在类中,我重写了GetRolesForUser函数
public override string[] GetRolesForUser(string nickname)
{
return new string[] { _userService.GetRoleForUser(nickname) };
}
UserService在UserRepository中调用此LINQ查询(此行抛出System.InvalidOperationException:&#39;由于DbContext已被释放,因此无法完成操作。&#39;)
public string GetRoleForUser(string nickname)
{
return DbContext.Users.Where(u => u.Nickname == nickname).FirstOrDefault().Role.Name;
}
有关如何解决此问题的任何提示?您不能通过构造函数将依赖项注入RoleProvider,因此我必须使用DependencyResolver.Current.GetService()。
答案 0 :(得分:0)
看起来您的SiteRole
课程的生命周期比注入的IUserService
更长。您应该检查它是否真的是问题的根源,并使用您的DI容器API调整注册服务的生命周期。以下是不同容器的一些链接:Autofac,NInject,Unity,Simple injector。
并且,可能会稍微更改您的SiteRole
类型 - 使用属性来生成UserService
而不是字段,在SiteRole
实例化时使用该字段创建唯一的实例。
public SiteRole()
{
// this field should be removed
// _userService = DependencyResolver.Current.GetService<IUserService>();
}
// this property should be used instead of field
private IUserService UserService
{
get { DependencyResolver.Current.GetService<IUserService>(); }
}
或者用现代语法
private IUserService UserService => DependencyResolver.Current.GetService<IUserService>();
但要小心并检查您是否未获得创建的UserService
个实例的不受控制的计数,例如,如果它在DI容器中配置为每次调用的实例。
答案 1 :(得分:0)
我通过这样做解决了这个问题:
virtual Owned<IUserService> ResolveUserService()
=> DependencyResolver.Current.GetService<Owned<IUserService>>();
使用Using语句调用GetRolesForUser方法中的服务:
public override string[] GetRolesForUser(string nickname)
{
using(var userService = ResolveUserService())
{
return new string[] {userService.Value.GetRoleForUser(nickname) };
}
}
在旁注中,DbContext是在RepositoryBase中构建的。我正在为我的项目使用通用存储库模式。
public abstract class RepositoryBase<T> where T : class
{
#region properties
private StoreEntities dataContext;
private readonly IDbSet<T> dbSet;
protected IDbFactory DbFactory
{
get;
private set;
}
protected StoreEntities DbContext
{
get { return dataContext ?? (dataContext = DbFactory.Init()); }
}
#endregion
protected RepositoryBase(IDbFactory dbFactory)
{
DbFactory = dbFactory;
dbSet = DbContext.Set<T>();
}
#region Implementation of defaults
public virtual void Add(T entity)...........
感谢您的帮助!