SetterProperty injection using structuremap to Asp.Net MVC ActionFilter
Asked Answered
A

1

5

Why I am not able to inject the SetterProperty via StructureMap to an 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;
    }
Advert answered 14/11, 2013 at 12:24 Comment(1)
Dear your question help me i my problem i miss the [SetterProperty] in my code and it work if you want to see my code then follow the link it have complete detail #23386844Comras
S
9

You need to utilize the 'BuildUp' method off the ObjectFactory.

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);
    }

Then you can create a new FilterAttributeFilterProvider like this:

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;
    }
}

Then finally add your custom filter provider to the .net pipeline.

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);
    }

Hope this helps!

wm

Seligmann answered 20/12, 2013 at 21:35 Comment(1)
This works like a charm, provided the injected property is public (spent half an hour on this, while injection fails silently if no public property is found to be set).Expressly

© 2022 - 2024 — McMap. All rights reserved.