2017-07-03 81 views
3

我想要得到這樣的工作:注入工廠Func鍵與ASP.NET核心DI

public class FooService : IFooService { 
    public FooService(Func<IBarService> barFactory) { ... } 
} 
public class BarService : IBarService, IDisposable { ... } 

services.AddSingleton<IFooService, FooService>(); 
services.AddTransient<IBarService, BarService>(); 
services.AddSingleton<Func<IBarService>>(ctx =>() => ctx.GetService<IBarService()); 

這個工程就解決BarService實例,但我無法弄清楚如何妥善管理其使用期限。當我做這裏面的FooService成員之一:

using (var bar = _barFactory()) 
{ 
    ... 
} 

我得到一個ObjectDispoedException

System.ObjectDisposedException:無法訪問已釋放的對象。造成這種錯誤的一個常見原因是處理從依賴注入解決的上下文,然後嘗試在應用程序的其他地方使用相同的上下文實例。如果您在上下文中調用Dispose(),或者在使用語句中包裝上下文,則可能會發生這種情況。如果您正在使用依賴注入,則應該讓依賴注入容器負責處理上下文實例。

但是,如果我只是做var bar = _barFactory();,沒有using語句,我沒有辦法向DI容器發信號告訴我已完成實例,並且可以處理它。

這裏的正確方法是什麼?


(旁註:是的,我知道有些人會反對說,一個單獨的服務不應該依賴於一個臨時服務這不是這裏發生了什麼;在所述單獨服務是依賴於一個單身工廠,產生短暫的實例然後單使用的臨時服務的一個或兩個語句,然後用它做,所以這裏應該沒有實際的壽命問題)

回答

2

documentation描述:。

容器將爲其創建的IDisposable類型調用Dispose。但是,如果您自己將實例添加到容器,則不會將其丟棄。

所以只是不要使用using聲明,所有應該都可以。

+0

但*當*它會調用'Dispose'?它如何知道我已完成實例? –

+1

@TomasLycken容器擁有'List ',它在作用域的末尾放置'Transient'和'Scoped'對象(默認的ASP.NET Core作用域是Web請求)。 https://stackoverflow.com/a/40845639/5112433 –