5

Warum kann ich den SetterProperty über StructureMap nicht in einen MVC ActionFilter injizieren?SetterProperty Injection mit Strukturmap zu Asp.Net 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; 
    } 
+0

Lieber Ihre Frage mir helfen, ich mein Problem vermisse ich die [SetterProperty] in meinem Code und es funktioniert, wenn Sie meinen Code sehen wollen, dann folgen Sie dem Link auf Vollständigkeit Detail haben http://stackoverflow.com/questions/23386344/asp-net-mvc-5-benutzerdefinierte-aktion-filter-mit-strukturkarte – Developerzzz

Antwort

9

Sie müssen die "BuildUp" -Methode von der ObjectFactory verwenden.

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

Dann können Sie eine neue FilterAttributeFilterProvider wie folgt erstellen:

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

Dann endlich Ihre benutzerdefinierte Filter-Anbieter für die .net-Pipeline hinzuzufügen.

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

Hoffe, das hilft!

wm

+0

Dies funktioniert wie ein Zauber, vorausgesetzt, die injected-Eigenschaft ist öffentlich (verbrachte eine halbe Stunde für diese, während Injektion fehlschlägt still, wenn keine Öffentlichkeit Eigenschaft wird gefunden eingestellt). –