问题
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