2015-08-28 24 views
4

我正在構建一個使用SimpleInjector進行依賴注入的應用程序(Xamarin.Forms,PCL和iOS,如果相關)。到目前爲止,使用SimpleInjector 3的最新版本已經很棒了,我正在更新我的代碼以使用新的API。不幸的是,我在某個註冊中遇到了一些麻煩。SimpleInjector 3將註冊視爲暫時的,即使使用`RegisterSingleton()`

這裏的基本流程:

  • 註冊一個ISQLitePlatform(在Windows,iOS版,Android版等)來處理特定於平臺的位(SQLite的API,文件I/O等)
  • 寄存器引導程序將負責創建數據庫文件,設置所有表/類型映射等。
  • 註冊將創建我們的數據訪問提供程序的lambda,使用引導程序設置數據庫並返回訪問提供程序

然後應用程序可以使用數據訪問提供程序在數據庫上打開事務 - IDataAccessProvider接口只有一個方法,即NewTransaction(),該方法返回帶有通用CRUD方法的工作單元對象。該IDataAccessProvider還實現IDisposableDispose()方法處理清理,關閉打開的連接/交易等

問題是這些註冊:

container.RegisterSingleton<ISQLitePlatform, SQLitePlatformIOS>(); 
container.RegisterSingleton<ILocalDataBootstrapper, SQLiteDataBootstrapper>(); 
container.RegisterSingleton<IDataAccessProvider>(
    () => container.GetInstance<ILocalDataBootstrapper>().DataAccessProvider); 

出於某種原因,在啓動時我得到的diagnostic warningSQLiteDataAccessProviderIDisposable並且已被註冊爲瞬態。我可以處理 - 處理正在正確的位置處理 - 但是令我困惑的是,由於我使用的是RegisterSingleton(),所以它肯定是而不是被註冊爲瞬態。

這是一個使用RegisterSingleton()而不是實例創建lambda的怪癖嗎?這是一個錯誤嗎?或者我錯過了我應該做的事情?

回答

3

最可能的原因爲什麼發生這種情況是地方在你的代碼做以下電話:

container.GetInstance<SQLiteDataAccessProvider>(); 

或者你有依賴於這個具體的類型,而不是抽象構造函數(在這種情況下,你也可以期待其他的警告)。

由於SQLiteDataAccessProvider沒有註冊爲「自身」(但僅僅通過它的IDataAccessProvider抽象),簡單注入器將爲您解析此類型,默認情況下,簡單注入器將使此類型爲瞬態。

通過這樣做,新的註冊被添加到簡單注射器;你將能夠在調試器中看到。有一個IDataAccessProvider的單身人士註冊和SQLiteDataAccessProvider的臨時註冊。

現在因爲有一個SQLiteDataAccessProvider的臨時註冊,Simple Injector會警告您這個實例不會自動處理。

解決方法是刪除GetInstance<SQLiteDataAccessProvider>()調用(或更改ctor參數以使用抽象),並將其替換爲GetInstance<IDataAccessProvider>()的調用。

+0

我沒有調用'GetInstance ()',但我確實有一個構造函數,它將'SQLiteDataAccessProvider'作爲參數。這是一個自動完成的滑動,因此將其切換到IDataAccessProvider進行修復。謝謝! – anaximander

+0

你也應該有一個短路依賴警告,以及:https://simpleinjector.readthedocs.org/en/latest/ShortCircuitedDependencies.html – Steven

+0

不,我沒有得到那一個,但它可能是一個隱藏其他。還有其他一些警告,所以我主要是一次只關注一個。 – anaximander