2017-04-02 37 views
-1

试图围绕依赖注入打包头,它来自静态类和实例化类的世界。这是我现在拥有的。非控制器类的依赖注入并调用它们

[SomeFilter] 
public class AController : Controller 
{ 
    private readonly IOptions<AppSettings> _appSettings; 

    public AController(IOptions<AppSettings> appSettings) 
{ 
    _appSettings = appSettings; 
} 

// GET: /characters/ 
public IActionResult Index() 
{ 
    //do something 
} 

SomeFilter立即调用,而做到这一点:

public class SomeFilter: ActionFilterAttribute, IActionFilter 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     OtherClass.RunMe(); 
    } 
} 

OtherClass看起来是这样的:

public class OtherClass 
{ 
    private readonly IOptions<AppSettings> _appSettings; 

    public OtherClass(IOptions<AppSettings> appSettings) 
{ 
    _appSettings = appSettings; 
} 

public RunMe() 
{ 
    //do something 
} 

我也有注册为Startup.cs一个service.Singleton OtherClass 。

我收到一个错误,指出:“一个对象引用对于非静态字段是必需的”对于OtherClass.RunMe();呼叫。我假设我可以从我的代码中的任何地方调用这个类,而不必创建它的新实例?从本质上讲,我如何从其他类使用依赖注入调用方法?

回答

0

您无法在过滤器上进行构造函数注入。这全是关于运行时间顺序。当您尝试在构造函数上注入时,您的IoC容器此刻无法访问。你应该使用属性/ setter注入。

我更喜欢使用结构图容器来做到这一点。因为结构图很容易应用任何类型的注入。例如,当你有这样的过滤器注册表

public class ActionFilterRegistry : Registry 
    { 
     public ActionFilterRegistry(Func<IContainer> containerFactory) 
     { 
      For<IFilterProvider>().Use(
       new StructureMapFilterProvider(containerFactory)); 

      Policies.SetAllProperties(x => 
       x.Matching(p => 
        p.DeclaringType.CanBeCastTo(typeof(ActionFilterAttribute)) && 
        p.DeclaringType.Namespace.StartsWith("YourNameSpace") && 
        !p.PropertyType.IsPrimitive && 
        p.PropertyType != typeof(string))); 
     } 
    } 

而你注册它在你的global.asax(喜欢)或你的启动类之一。 示例app_Start方法。

DependencyResolver.SetResolver(new StructureMapDependencyResolver(() => Container ?? ObjectFactory.Container)); 
      ObjectFactory.Container.Configure(cfg => 
      { 
       cfg.AddRegistry(new StandardRegistry()); 
       cfg.AddRegistry(new ControllerRegistry()); 
       cfg.AddRegistry(new ActionFilterRegistry(() => Container)); 
       cfg.AddRegistry(new MvcRegistry());     
      }); 

然后,您可以使用任何与注射过滤器。但要注意,你不应该像你那样使用构造器注入。

0

我找到了一种方法来注入过滤器使用

[ServiceFilter(typeof(MyFilter))] 

,而不是仅仅

[MyFilter] 

和内过滤器的

(ActionExecutingContext context) 
{ 
    var controller = context.Controller as Controller. 
    controller.whateverIneed 
} 

现在,这为我提供了我需要在过滤器内。我也意识到,我不能删除使用new创建其他类的引用的需求,因为我的印象是Core的依赖关系是“不再有new”。这与我仍然在掌握的Core基本原理有关。

我最终做的是创建新的类来完成一些工作,但它们设置为服务并在startup.cs中注册。我仍在苦苦寻找如何混合注册服务(我可以注入)和工作者类的新实例(通常持有静态信息),并在它们之间传递信息。