使用structuremap将SetterProperty注入到Asp.Net MVC ActionFilter

时间:2013-11-14 12:24:02

标签: asp.net-mvc-4 dependency-injection structuremap actionfilterattribute

为什么我无法通过SetterPropertyStructureMap注入MVC​​ ActionFilter?

public class LockProjectFilter : ActionFilterAttribute
    {
        [SetterProperty]
        public ISecurityService SecurityService { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var loggedinStaffId = SecurityService.GetLoggedInStaffId();
            if (loggedinStaffId == 1)
                throw new ArgumentNullException();
            base.OnActionExecuting(filterContext);
        }
    }


    public static IContainer Initialize()
    {
        ObjectFactory.Initialize(x =>
                         {
                             x.Scan(scan =>
                                            {
                                                scan.TheCallingAssembly();
                                                scan.WithDefaultConventions();
                                                scan.AssemblyContainingType<ISecurityService>();
                                            });
                             x.SetAllProperties(p => p.OfType<ISecurityService>());
                             //x.ForConcreteType<LockProjectFilter>().Configure
                                // .Setter(c => c.SecurityService).IsTheDefault();
                         });
        return ObjectFactory.Container;
    }

1 个答案:

答案 0 :(得分:9)

您需要在ObjectFactory上使用'BuildUp'方法。

http://docs.structuremap.net/ConstructorAndSetterInjection.htm#section4

[Test]
    public void create_a_setter_rule_and_see_it_applied_in_BuildUp_through_ObjectFactory()
    {
        var theGateway = new DefaultGateway();
        ObjectFactory.Initialize(x =>
        {
            x.ForRequestedType<IGateway>().TheDefault.IsThis(theGateway);

            // First we create a new Setter Injection Policy that
            // forces StructureMap to inject all public properties
            // where the PropertyType is IGateway
            x.SetAllProperties(y =>
            {
                y.OfType<IGateway>();
            });
        });

        // Create an instance of BuildUpTarget1
        var target = new BuildUpTarget1();

        // Now, call BuildUp() on target, and
        // we should see the Gateway property assigned
        ObjectFactory.BuildUp(target);

        target.Gateway.ShouldBeTheSameAs(theGateway);
    }

然后你可以像这样创建一个新的FilterAttributeFilterProvider:

public class DependencyResolverFilterProvider : FilterAttributeFilterProvider
{
    public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        var filters = base.GetFilters(controllerContext, actionDescriptor);

        foreach (var filter in filters)
        {
            //DI via Setter Injection
            DependencyResolver.BuildUp(filter.Instance);
        }

        return filters;
    }
}

然后最后将自定义过滤器提供程序添加到.net管道。

private static void RegisterProviderAndFilters()
    {
        var oldProvider = FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider);
        FilterProviders.Providers.Remove(oldProvider);
        FilterProviders.Providers.Add(new DependencyResolverFilterProvider());

        RegisterGlobalFilters(GlobalFilters.Filters);
    }

希望这有帮助!

WM