【发布时间】:2014-06-28 09:01:21
【问题描述】:
我有一个 ASP.NET MVC 4 应用程序,它需要使用预先存在的用户/角色成员资格模型。我这样做的方法是实现一个自定义的 ASP.NET RoleProvider 来管理访问,它使用实体框架存储库从数据库中读取用户数据。读取用户角色的方法如下所示,但所有的方法实现都遵循这种模式:
public class OurRoleProvider : RoleProvider
{
private IUserRepository _userRepository;
public OurRoleProvider() : this(Container.Resolve<IUserRepository>())
{
}
public OurRoleProvider(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public override string[] GetRolesForUser(string username)
{
var user = _userRepository.GetUserByUserName(username);
if (user.Roles.IsNullOrEmpty())
return new string[0];
return user.Roles.Select(r => r.RoleName).ToArray();
}
}
我现在遇到了in this post 描述的问题。因为 RoleProvider 的单个实例在应用程序的生命周期中被重复使用,并且所有其他功能都会创建它自己的每个请求 DbContext 来持久化数据,所以对 User 配置文件所做的更改不会被 RoleProvider 反映,直到重新启动应用程序,因为它的底层 DbContext 没有被刷新。这意味着您可以从角色中删除用户,并且他们仍然可以访问该角色的功能,直到应用重新启动。
我尝试在 RoleProvider 方法中创建一个新的存储库实例,即在 GetRoleForUser() 中:
var user = _userRepository.GetUserByUserName(username);
变成
var userRepository = Container.Resolve<IUserRepository>();
var user = userRepository.GetUserByUserName(username);
这解决了问题,但会破坏不使用 DI 容器并通过构造函数注入模拟存储库的单元测试。会有很多单元测试需要重写。
如果可能的话,我想坚持使用自定义 RoleProvider 以利用 Authorize 属性等功能。我真正需要做的是根据每个请求重新实例化 RoleProvider 或强制 EF 存储库始终从数据库更新。到目前为止,我还没有找到一种方法来做到这一点。这可能吗?还是有更好的解决方案?
【问题讨论】:
标签: c# asp.net asp.net-mvc entity-framework roleprovider