我使用 Autofac 和 asp.net MVC 5,以及通用存储库模式
我创建自定义 RoleProvider
自定义角色提供者
namespace Web.Utility.Classes
{
class GoldenBodyProvider : RoleProvider
{
private readonly IUnitOfWork _unitOfWork;
private readonly IService _service;
public GoldenBodyProvider()
{
}
public GoldenBodyProvider(IUnitOfWork unitOfWork, IService service)
{
_unitOfWork = unitOfWork;
_service = service;
}
public override bool IsUserInRole(string username, string roleName)
{
throw new NotImplementedException();
}
public override string[] GetRolesForUser(string username)
{
var role = (from u in _service.UserRepository.GetAll()
join r in _service.RoleRepository.GetAll() on u.RoleId equals r.Id
where u.MobileNumber == username
select r.RoleInSystem).ToArray();
return role;
}
public override void CreateRole(string roleName)
{
throw new NotImplementedException();
}
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
throw new NotImplementedException();
}
public override bool RoleExists(string roleName)
{
throw new NotImplementedException();
}
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override string[] GetUsersInRole(string roleName)
{
throw new NotImplementedException();
}
public override string[] GetAllRoles()
{
throw new NotImplementedException();
}
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
throw new NotImplementedException();
}
public override string ApplicationName { get; set; }
}
}
在其中一个视图中调用User.IsInRole("Coach")
(该GetRolesForUser
方法在 RoleProvider 中调用)。之后,GetRolesForUser
在 RoleProvider 的方法中给我一个错误:
你调用的对象是空的。
指向的错误_service.UserRepository.GetAll()
,此方法是通过 autofact 注入到 RoleProvider
源错误:
第 31 行:public override string[] GetRolesForUser(string username)
第 32 行:{
第 33 行:var role =(来自 _service.UserRepository.GetAll() 中的 u
第 34 行:在 _service.RoleRepository.GetAll() 中加入 r u.RoleId 等于 r.Id
第 35 行:其中 u.MobileNumber == 用户名
源文件:I:\GBWork\GoldenBody\Web\Utility\Classes\GoldenBodyProvider.cs 行:33
GetAll()
GenericRepository 模式中的方法是:
public virtual List<T> GetAll()
{
return _t.AsParallel().ToList();
}
我认为注射不能正常工作。
自动配置:
#region Autofac
var builder = new ContainerBuilder();
#region Registery
#region MVC Register
//This allows you to add properties to your filter attributes and any matching dependencies that are registered in the container will be injected into the properties.
builder.RegisterFilterProvider();
// You can register controllers all at once using assembly scanning...
builder.RegisterControllers(typeof(Global).Assembly);
builder.RegisterModule<AutofacWebTypesModule>();
builder.RegisterAssemblyTypes(Assembly.Load("ServiceLayer"))
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.InstancePerRequest();
builder.RegisterType(typeof(GoldenBodyDb)).As(typeof(IUnitOfWork)).InstancePerRequest();
#endregion
#region WebApi
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); //Register WebApi Controllers
//زیرا کنتلر های وب ای پی آی در همین اسمبلی می باشد
#endregion
#endregion
var container = builder.Build();
// Set the dependency resolver for Web API.
var webApiResolver = new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = webApiResolver;
// Set the dependency resolver for MVC.
var mvcResolver = new AutofacDependencyResolver(container);
DependencyResolver.SetResolver(mvcResolver);
#endregion
我哪里做错了?我的问题在哪里?解决办法是什么?
看起来您正在使用 Identity 并实现自定义角色提供程序。我假设您没有使用 OWIN(在您的 autofac 配置中没有任何相关内容)。我还假设您没有使用 SignInManager、UserManager 或 AuthenticationManager,您只是使用您的 RoleManager 配置,<system.web>
其中包含<roleManager>
映射到您的GoldenBodyProvider
类的部分,带有<authentication mode="Windows" />
.
如果我在这里做出错误的假设,我的回答将毫无用处。如果您在问题中包含此信息,将会非常有帮助。否则无法提供正确答案。
继续所有这些假设,据我所知,您不能将构造函数参数注入到这样配置的 RoleProvider。它需要一个无参数的构造函数。我可以想到几种可能的解决方案:
解决方案一:尽量使用autofac属性注入,而不是构造函数参数的注入。你需要像这样注册你的提供者(注意:你可能想要添加一个生命周期范围配置):
builder.RegisterType<GoldenBodyProvider>().PropertiesAutowired();
并将您的只读字段转换为可写属性:更改此:
private readonly IService _service;
private readonly IUnitOfWork _unitOfWork;
对此:
public IService _service { get; set; }
public IUnitOfWork _unitOfWork { get; set; }
(更新:上面的原始代码将属性定义为private
,我将其更改为public
。属性注入要求属性具有公共设置器,因此如果您需要保持属性私有,则此解决方案不适合您。在这里您可以找到一个此问题的解决方法。)
关于属性注入的更多信息在这里。
解决方案 2:您可以在没有依赖注入的情况下实现您的 RoleProvider 方法,只需在每次需要使用它时直接实例化身份数据库上下文,如本答案所示(查看 class 的代码示例AppRoleProvider
)。
public class AppRoleProvider : RoleProvider
{
public override string[] GetAllRoles()
{
using (var userContext = new UserContext())
{
... //Do the query with userContext and return some value
}
}
...
}
解决方案 3:使用服务定位器,如本答案所述。在无参数构造函数的代码中,显式Resolve
地实例化您需要的字段。这个解决方案不是很干净。Resolve
应避免在运行时访问容器并执行操作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句