2017-04-02 36 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中註冊。我仍在苦苦尋找如何混合註冊服務(我可以注入)和工作者類的新實例(通常持有靜態信息),並在它們之間傳遞信息。