Custom AuthorizeAttribute Ninject Property Injection doesn't work (injected property have sub dependant services which need to be injected)

陌路散爱 提交于 2019-12-23 18:05:38

问题


I think the specifics of my question are very much different than the other similar questions which I have red.

I know that when I have custom AuthorizeAttribute I can't inject dependencies with the constructor. This is because the constructor will take the parameters - in my case the permission strings.

 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public class UserAllCSPermissionBasedAuthFilter : AuthorizeAttribute
    {

I am depending on authorization service, that's why I am injected that using property injection.

[Inject]
  public IAuthorizationService _authorizationService { get; set; }

The problem is that this service depends on another service - userservice which talks directly with repository and dbcontext. I have specify for my db context to live in request scope. This is cousing an exception - "The operation cannot be completed because the DbContext has been disposed." When I looked at the code this is happening when the autorization service calls userservice which asks the dbcontext for some data. How should I avoid this happening?

  public class AuthorizationService : IAuthorizationService
    {
        private readonly ICommonRepository _commonRepository;
        private readonly IRepositoryBase<UsersInRolesEntity> _repositoryUsersInRoles;
        private readonly IRepositoryBase<UserCustomerRolesEntity> _repositoryCurstomerRoleEntities;
        private readonly ISqlCustomersRepository _sqlCustomerRepository;
        private readonly IRoleService _roleService;
        private readonly IUserService _userService;
        private readonly IPermissionService _permissionService;

        public AuthorizationService(
            IRepositoryBase<UsersInRolesEntity> repositoryUsersInRoles,
            IRepositoryBase<UserCustomerRolesEntity> repositoryCurstomerRoleEntities,
            ICommonRepository commonRepository,
            ISqlCustomersRepository sqlCustomerRepository,
            IRoleService roleService,
            IUserService userService,
            IPermissionService permissionService
            )
        {

回答1:


Steven, thanks for the support, I was looking at the articles you suggested and the Ninject manual. I totally agree with you that Property Binding is not a nice idea. But couldn't get why we are doing all of the things in the article (https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=98). I suppose that was written before the Ninject authors added a way to configure attribute binding using their framework (https://github.com/ninject/Ninject.Web.Mvc/wiki/Filter-configurations).

I had a look at my Ninject configuration. For my authorization filters I had something like this:

#region UserAllCSPermissionBasedAuthFilter

kernel.BindFilter<UserAllCSPermissionBasedAuthFilter>(FilterScope.Action, 0)
    .WhenActionMethodHas<UserAllCSPermissionBasedAuthFilter>()
    .WithConstructorArgumentFromActionAttribute<UserAllCSPermissionBasedAuthFilter>("permissionEnums", att => att.PermissionEnums);

kernel.BindFilter<UserAllCSPermissionBasedAuthFilter>(FilterScope.Controller, 0)
    .WhenActionMethodHas<UserAllCSPermissionBasedAuthFilter>()
    .WithConstructorArgumentFromControllerAttribute<UserAllCSPermissionBasedAuthFilter>("permissionEnums", att => att.PermissionEnums);

#endregion

I have a couple of these and then the light-bulb moment came :) I just saw a small mistake in my configuration. Instead of using:

kernel.BindFilter<UserAllCSPermissionBasedAuthFilter>(FilterScope.Controller, 0)
    .WhenActionMethodHas<UserAllCSPermissionBasedAuthFilter>()
    .WithConstructorArgumentFromControllerAttribute<UserAllCSPermissionBasedAuthFilter>("permissionEnums", att => att.PermissionEnums);

That should actually be:

kernel.BindFilter<UserAllCSPermissionBasedAuthFilter>(FilterScope.Controller, 0)
    .WhenControllerHas<UserAllCSPermissionBasedAuthFilter>()
    .WithConstructorArgumentFromControllerAttribute<UserAllCSPermissionBasedAuthFilter>("permissionEnums", att => att.PermissionEnums);

WhenActionMethodHas -> WhenControllerHas.

That miraculously fixed everything. Now works perfectly and the code looks fine to me without additional coding changes.



来源:https://stackoverflow.com/questions/29971605/custom-authorizeattribute-ninject-property-injection-doesnt-work-injected-prop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!