使用Unity注入的依赖关系到自定义ActionFilter [英] Using Unity to inject dependencies into a custom ActionFilter

查看:925
本文介绍了使用Unity注入的依赖关系到自定义ActionFilter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我有一个自定义的ControllerFactory到我注入我的容器统一:

At the moment, I have a custom ControllerFactory into which I inject my Unity container:

在Global.asax中的Application_Start():

in global.asax Application_Start():

var container = InitContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));

var factory = new UnityControllerFactory(container);
ControllerBuilder.Current.SetControllerFactory(factory);

在控制器工厂设置我的控制器使用像这样的自定义ActionInvoker:

In the controller factory I set my controllers to use a custom ActionInvoker like so:

protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
    var controller = base.GetControllerInstance(requestContext, controllerType) as Controller;

    if (controller != null)
        controller.ActionInvoker = new UnityActionInvoker(_container);

    return controller;
}

最后,在我的自定义ActionInvoker,我试图集结行动使用ActionInvokers容器被调用:

Finally in my custom ActionInvoker, I attempt to buildup actions being invoked using the ActionInvokers container:

protected override ActionExecutedContext InvokeActionMethodWithFilters(
        ControllerContext controllerContext,
        IList<IActionFilter> filters,
        ActionDescriptor actionDescriptor,
        IDictionary<string, object> parameters)
{
    var builtUpFilters = new List<IActionFilter>();

    foreach (IActionFilter actionFilter in filters)
    {
        builtUpFilters.Add(_container.BuildUp<IActionFilter>(actionFilter));
    }

    return base.InvokeActionMethodWithFilters(controllerContext, builtUpFilters, actionDescriptor, parameters);
}

下面是正在建立的ActionFilters之一的示例:

Here is an example of one of the ActionFilters that is being built up:

public class PopulatRolesAttribute : ActionFilterAttribute, IActionFilter
{
    private const string RolesKey = "roles";

    [Dependency]
    public Func<IMetadataService> Service { get; set; }

    public PopulatRolesAttribute()
    {
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.Controller.ViewData[RolesKey] == null)
        {
            filterContext.Controller.ViewData[RolesKey] = Service().GetRoles();
        }
    }
}

问题是,在我的自定义ActionFilterAttribute公共财产是从来没有注入任何东西,但它仍然在执行空!我不明白为什么我的过滤器没有被正确的容器builtup。被注入的类型是否正确注册,像这样:

The problem is that the public property on my custom ActionFilterAttribute is never injected with anything, it remains null on execution! I cannot see why my filter is not being correctly builtup by the container. The type being injected is registered properly, like so:

container.RegisterInstance(new ChannelFactory<IMetadataService>(
    new BasicHttpBinding(),
    new EndpointAddress("http://example.com/ABSApplication/MetadataService.svc")));

container.RegisterInstance<Func<IMetadataService>>(
    () => container.Resolve<ChannelFactory<IMetadataService>>().CreateChannel());

和也正在申请别处注射(虽然未通过.Buildup)。这是pretty大致相同的过程,后跟此<一个href=\"http://$c$cclimber.net.nz/archive/2009/02/10/how-to-use-ninject-to-inject-dependencies-into-asp.net-mvc.aspx\"相对=nofollow>博客文章。我错过了什么一块拼图?

And is also being injected elsewhere in the application (Although not via .Buildup). This is pretty much the same process followed by this blog post. What piece of the puzzle am I missing?

推荐答案

我会做这个略有不同。我想:

I would do this slightly differently. I would:


  1. 安装unity.mvc3的NuGet包

  1. install the unity.mvc3 nuget package

调用bootstrapped.initialise(),如TXT文档中提到的包添加到项目

call the bootstrapped.initialise() as mentioned in the txt doc the package adds to the project

定义的初始化IMetadataService映射到你的具体类型

define your IMetadataService mapping in the initialize to your Concrete type

添加到IMetadataService你的构造函数

add IMetadataService to your constructor

您的实现,你引用的文章之间的区别是你用Func键,其中林不知道如果这对组合在这里添加了不同的问题。我想象它作为上述方法(不Func键)为我工作得很好。

The difference between your implementation and the article you references is you use Func, which Im not sure if that adds a different problem to the mix here. I have to imagine it does as the above method (without Func) works fine for me.

编辑:
布拉德·威尔逊的code工作得很好,我在这里:
<一href=\"http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html\">http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html

适用部位(请参阅上面的链接)

Applicable parts (please see the link above)

的Global.asax.cs

Global.asax.cs



protected void Application_Start() {
    // ...

    var oldProvider = FilterProviders.Providers.Single(
        f => f is FilterAttributeFilterProvider
    );
    FilterProviders.Providers.Remove(oldProvider);

    var container = new UnityContainer();
    var provider = new UnityFilterAttributeFilterProvider(container);
    FilterProviders.Providers.Add(provider);

    // ...
}

过滤器本身:



using System;
using System.Web.Mvc;
using Microsoft.Practices.Unity;

public class InjectedFilterAttribute : ActionFilterAttribute {

    [Dependency]
    public IMathService MathService { get; set; }

    public override void OnResultExecuted(ResultExecutedContext filterContext) {
        filterContext.HttpContext.Response.Write(
            String.Format("

The filter says 2 + 3 is {0}.

和UnityFilterAttributeFilterProvider.cs

and UnityFilterAttributeFilterProvider.cs



using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Practices.Unity;

public class UnityFilterAttributeFilterProvider : FilterAttributeFilterProvider {
    private IUnityContainer _container;

    public UnityFilterAttributeFilterProvider(IUnityContainer container) {
        _container = container;
    }

    protected override IEnumerable GetControllerAttributes(
                ControllerContext controllerContext,
                ActionDescriptor actionDescriptor) {

        var attributes = base.GetControllerAttributes(controllerContext,
                                                      actionDescriptor);
        foreach (var attribute in attributes) {
            _container.BuildUp(attribute.GetType(), attribute);
        }

        return attributes;
    }

    protected override IEnumerable GetActionAttributes(
                ControllerContext controllerContext,
                ActionDescriptor actionDescriptor) {

        var attributes = base.GetActionAttributes(controllerContext,
                                                  actionDescriptor);
        foreach (var attribute in attributes) {
            _container.BuildUp(attribute.GetType(), attribute);
        }

        return attributes;
    }
}

这篇关于使用Unity注入的依赖关系到自定义ActionFilter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆