簡體   English   中英

簡單注入器MVC ActionFilter依賴注入

[英]Simple injector MVC ActionFilter dependency injection

我一直在嘗試閱讀這篇文章 ,了解如何將依賴項注入到自定義LogActionFilter但我不能撒謊。 我很困惑,需要一些幫助才能達到終點(即將依賴項注入到我的自定義操作過濾器中,以及如何完成操作的解釋。到目前為止,我已經做到了:

IActionFilter:

public interface IActionFilter<TAttribute> where TAttribute : Attribute {
    void OnActionExecuting(TAttribute attribute, ActionExecutingContext context);
}

LogActionDecorator:

public class LogActionDecorator<TAttribute> : IActionFilter<TAttribute> 
    where TAttribute : Attribute {
    private readonly IActionFilter<TAttribute> _decoratee;
    private readonly IAccountManagementManager _iAccountManagementManager;

    public LogActionDecorator(
        IActionFilter<TAttribute> decoratee, 
        IAccountManagementManager iAccountManagementManager) {
        this._decoratee = decoratee;
        this._iAccountManagementManager = iAccountManagementManager;
    }

    public void OnActionExecuting(TAttribute attribute, ActionExecutingContext context) {
        this._decoratee.OnActionExecuting(attribute, context);
    }
}

ActionFilterDispatcher:

public class ActionFilterDispatcher : IActionFilter {
    private readonly Func<Type, IEnumerable> _container;

    public ActionFilterDispatcher(Func<Type, IEnumerable> container) {
        this._container = container;
    }

    public void OnActionExecuted(ActionExecutedContext filterContext) { }

    public void OnActionExecuting(ActionExecutingContext context) {
        var descriptor = context.ActionDescriptor;
        var attributes = descriptor.ControllerDescriptor.GetCustomAttributes(true)
            .Concat(descriptor.GetCustomAttributes(true))
            .Cast<Attribute>();

        foreach (var attribute in attributes) {
            Type filterType = typeof(IActionFilter<>)
                .MakeGenericType(attribute.GetType());
            IEnumerable filters = this._container.Invoke(filterType);

            foreach (dynamic actionFilter in filters) {
                actionFilter.OnActionExecuting((dynamic)attribute, context);
            }
        }
    }
}

LogActionFiter:

public class LogActionFilter : IActionFilter<ActionFilterAttribute> {
    private readonly IAccountManagementManager _iAccountManagementManager;
    public LogActionFilter(IAccountManagementManager iAccountManagementManager) {
        _iAccountManagementManager = iAccountManagementManager;
    }
    public void OnActionExecuting(
        ActionFilterAttribute attribute, ActionExecutingContext context) {
        var fg = _iAccountManagementManager.ReturnApplicationIDAsync();
    }
}

控制器:

[LogActionFilter] //Build error LogActionFilter is not an attribute class
public class AccountManagementController : Controller {

    public async Task<ActionResult> EndImpersonation() {
      //Do stuff
    }
}

有人可以幫助我將依賴項注入到自定義操作過濾器中,還可以解釋如何完成此操作嗎? DI有時真的很難理解

您必須使用ActionFilterAttribute而不是LogActionFilter標記控制器。

IActionFilter:

/// <summary>
/// My ActionFilter which takes an Attribute
/// </summary>
/// <typeparam name="TAttribute">The attribute type(E.g ActionFilterAttribute)</typeparam>
public interface IActionFilter<TAttribute> where TAttribute : Attribute {
    //My OnActionExecuting method which will be called when an Action is being executed. It can be extended to include other methods such as OnActionExecuted if required
    void OnActionExecuting(TAttribute attribute, ActionExecutingContext context);
}

ActionFilterDispatcher:

/// <summary>
/// The dispatcher(which gets added to the GlobalFilters) requires the simple injector container which contains all instances of injected classes.
/// Inherit from the MVC library IActionFilter in order to gain access to the OnActionExecuting method
/// </summary>
public class ActionFilterDispatcher : IActionFilter {
    private readonly Func<Type, IEnumerable> _container;

    public ActionFilterDispatcher(Func<Type, IEnumerable> container) {
        this._container = container;
    }

    public void OnActionExecuted(ActionExecutedContext filterContext) { }

    public void OnActionExecuting(ActionExecutingContext context) {
        var descriptor = context.ActionDescriptor;
        //Get all attributes on a controller/action and cast them to the generic Attribute class
        var attributes = descriptor.ControllerDescriptor.GetCustomAttributes(true)
            .Concat(descriptor.GetCustomAttributes(true))
            .Cast<Attribute>();

        //Foreach attribute call the OnActionExecuting method for the IActionFilter of the attribute(E.g LogActionDecoraor)
        foreach (var attribute in attributes) {
            Type filterType = typeof(IActionFilter<>).MakeGenericType(attribute.GetType());
            IEnumerable filters = this._container.Invoke(filterType);

            foreach (dynamic actionFilter in filters) {
                actionFilter.OnActionExecuting((dynamic)attribute, context);
            }
        }
    }
}

LogActionDecorator:

    /// <summary>
    /// This is where the decoratee(E.g. the LogActionFilter) gets called. It is also where the implementation is contained
    /// </summary>
    /// <typeparam name="TAttribute"></typeparam>
    public class LogActionDecorator<TAttribute> : IActionFilter<TAttribute> where TAttribute : Attribute {
        private readonly IActionFilter<TAttribute> _decoratee;

        public LogActionDecorator(IActionFilter<TAttribute> decoratee, IAccountManagementManager iAccountManagementManager) {
            this._decoratee = decoratee;
        }

        public void OnActionExecuting(TAttribute attribute, ActionExecutingContext context) {
            this._decoratee.OnActionExecuting(attribute, context);
        }
    }

LogActionFilter:

/// <summary>
/// My custom ActionFilter for the LogActionAttribute. This is the class which gets called to complete the implementation of the attribute
/// </summary>
public class LogActionFilter : IActionFilter<LogActionAttribute> {
    private readonly IAccountManagementManager _iAccountManagementManager;
    public LogActionFilter(IAccountManagementManager iAccountManagementManager) {
        _iAccountManagementManager = iAccountManagementManager;
    }
    public void OnActionExecuting(LogActionAttribute attribute, ActionExecutingContext context) {
        var fg = _iAccountManagementManager.ReturnApplicationIDAsync();
    }
}

LogActionAttribte:

/// <summary>
/// This is my custom ActionFilterAttribute. It is passive(contains no code) as the implementation will be taken care of in my LogActionFilter
/// </summary>
public class LogActionAttribute : ActionFilterAttribute {
}

位指示:

[LogActionAttribute] 
public class AccountManagementController : Controller {

    public async Task<ActionResult> EndImpersonation() {
      //Do stuff
    }
}

史蒂文是對的,我不明白本文的重點。 無論如何,這是我更新的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM