簡體   English   中英

解決Module類中的AutoFac依賴項

[英]Resolving AutoFac dependencies inside Module class

我是AutoFac的新手,目前我在app app中使用自定義模塊來啟動一些核心F#系統。 我正在使用的代碼是

var builder = new ContainerBuilder();
builder.RegisterType<DefaultLogger>().As<IDefaultLogger>();
builder.RegisterModule(new ConfigurationSettingsReader("autofac"));
builder.Build();

在我的app配置中,我有適當的邏輯來啟動相關系統。 我想訪問我的模塊中的DefaultLogger。 Module基類的元數據有以下選項可供我使用:

protected virtual void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration);

protected virtual void AttachToRegistrationSource(IComponentRegistry componentRegistry, IRegistrationSource registrationSource);

public void Configure(IComponentRegistry componentRegistry);

protected virtual void Load(ContainerBuilder builder);

到目前為止我只使用Load,我在構建器上看不到任何允許我進入日志記錄服務的方法。

使用autofac而不是使用RegisterType方法在模塊中注冊某些內容時,可以使用Register方法:

builder.Register(c =>
   {
       IComponentContext ctx = c.Resolve<IComponentContext();
       IDefaultLogger logger = ctx.Resolve<IDefaultLogger>();
       ...do something with logger...
       return ...return object you want to register...;
    });

答案結果非常簡單。 我剛剛將IComponentContext添加為Module的實現的依賴項

public class LocalActorSystemModule : Module {
    private IComponentContext m_ComponentContext; // A service for resolving dependencies required by this module

    public LocalActorSystemModule(IComponentContext componentContext) { 
        m_ComponentContext = componentContext;
    }

讓AutoFac為我注入IComponentContext。 這樣我就可以解決模塊內部所需的任何依賴關系。

使用每個IoC / DI容器的經驗法則: 解決一次! =>然后,您將獲得所請求對象的所有依賴項。 如果你試圖多次解決,注冊其他對象(在此期間)你陷入了地獄。 真。 如果您想在不同的地點和時間點(從中央注冊解析)檢索不同目的的對象,您可能正在尋找服務定位器模式 (但這通常也被描述為反模式 )。

模塊的目的是將相關注冊(有條件地)捆綁為Autofac文檔中的statet

模塊是一個小類,可用於在“Facade”后面捆綁一組相關組件,以簡化配置和部署。

...因此,如果它們只是注冊的總和並且容器尚未構建,則您無法立即解析和使用(甚至以前注冊過的)組件(除了通過OnActivate *鈎子在注冊者本身上調用方法之外)當使用實例注冊時,但我認為這不是你的例子的情況)。 組件處於注冊狀態,但完整的上下文尚未准備好解決。 如果您覆蓋另一個模塊中的注冊會發生什么? 然后你會注入不同的對象......糟糕的主意。 也許您應該重新考慮您的應用程序設計以及哪些對象具有哪些職責。

順便說一句:日志記錄是一個跨領域的問題,通常通過調用單獨的靜態工廠或服務而不是執行構造函數/屬性注入來“注入/解決”(例如,參見Common.Logging的用法)。

public class MyModule : Module
{
    private static readonly ILog Log = LogManager.GetLogger<MyModule>();

    protected override void Load(ContainerBuilder builder)
    {
        Log.Debug(msg => msg("Hello")); // log whatever you want here
    }
}

您還可以嘗試使用AOP庫並將依賴項編織到模塊中(使用反射)。 但我認為僅僅嘗試登錄模塊是不值得的。

無論如何:@ mr100已經在注冊過程中顯示了正確的用法。 在那里你也可以處理激活等但不能記錄模塊本身。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM