Dot-Net

Autofac 和 Func 工廠

  • December 14, 2013

我正在使用 Caliburn.Micro 和 Autofac 開發應用程序。

在我的組合根中,我現在面臨 Autofac 的一個問題:我必須將全域使用的 IEventAggregator 注入到我的 FirstViewModel 中,並且必須將第二個 IEventAggregator 注入到我的 FirstViewModel 中,它只能由這個 FirstViewModel 及其子項使用。

我的想法是將第二個注入為Owned<IEA>,並且它可以工作,容器提供了一個不同的 IEA 實例。

public FirstViewModel(
   IEventAggregator globalEA,
   IEventAggregator localEA,
   Func<IEventAggregator, SecondViewModel> secVMFactory) {}

當我必須向 SecondViewModel 提供事件聚合器時,問題就來了。

要創建 SecondViewModel,我使用工廠方法作為Func<IEA, SecondVM>. SecondViewModel 的建構子如下:

public SecondViewModel(IEventAggregator globalEA, IEventAggregator localEA) {}

我希望容器將第一個作為註冊的注入,第二個將是Func<IEA, SecVM>.

這是我在容器中註冊的功能:

builder.Register<Func<IEventAggregator, SecondViewModel>>(
    c =>
        (ea) =>
        {
            return new SecondViewModel(
                c.Resolve<IEventAggregator>(),
                ea);
        }
);

但是當它被呼叫時,FirstViewModel我得到以下錯誤:

Autofac.dll 中出現“System.ObjectDisposedException”類型的異常,但未在使用者程式碼中處理

附加資訊:此解析操作已結束。使用 lambda 註冊組件時,無法儲存 lambda 的 IComponentContext ‘c’ 參數。相反,要麼從“c”再次解析 IComponentContext,要麼解析基於 Func<> 的工廠以從中創建後續組件。

我不明白問題出在哪裡,你能幫我嗎,我錯過了什麼?

謝謝你。

secVMFactory您在建構子之外呼叫,FirstViewModel因此到那時 ResolveOperation 已被釋放,並且在您的工廠方法c.Resolve中將引發異常。

幸運的是,異常消息非常具有描述性,並告訴您該怎麼做:

使用 lambda 註冊組件時,無法儲存 lambda 的 IComponentContext ‘c’ 參數。相反,要麼從 ‘c’ 再次解析 IComponentContext

因此,c.Resolve您不需要呼叫IComponentContextfromc並在您的工廠 func 中使用它:

builder.Register&lt;Func&lt;IEventAggregator, SecondViewModel&gt;&gt;(c =&gt; {
    var context = c.Resolve&lt;IComponentContext&gt;();
    return ea =&gt; { 
         return new SecondViewModel(context.Resolve&lt;IEventAggregator&gt;(), ea); 
    };
});

引用自:https://stackoverflow.com/questions/20583339