简单注入器3认为注册是暂时的,即使使用了' RegisterSingleton() '
本文关键字:RegisterSingleton 注入器 注册 简单 | 更新日期: 2023-09-27 18:10:25
我正在构建一个应用程序(Xamarin)。form, PCL和iOS(如果它是相关的)使用Simple Injector进行依赖注入。到目前为止,它的使用效果非常好,随着最近发布的Simple Injector 3,我正在更新我的代码以使用新的API。不幸的是,我在一个特定的注册中遇到了一点麻烦。
基本流程如下:
- 注册一个
ISQLitePlatform
(Windows, iOS, Android等)来处理平台特定的位(SQLite API,文件I/O等) - 注册一个引导程序,它将负责创建数据库文件,设置所有表/类型映射等。
- 注册一个lambda,它将创建我们的数据访问提供程序,使用引导程序来设置数据库,并返回访问提供程序
应用程序可以使用数据访问提供者打开数据库上的事务- IDataAccessProvider
接口只有一个方法,NewTransaction()
,它返回一个具有通用CRUD方法的工作单元对象。IDataAccessProvider
还实现了IDisposable
, Dispose()
方法处理清理、关闭打开的连接/事务等。
问题是这些注册:
container.RegisterSingleton<ISQLitePlatform, SQLitePlatformIOS>();
container.RegisterSingleton<ILocalDataBootstrapper, SQLiteDataBootstrapper>();
container.RegisterSingleton<IDataAccessProvider>(
() => container.GetInstance<ILocalDataBootstrapper>().DataAccessProvider);
由于某种原因,在启动时,我得到SQLiteDataAccessProvider
是IDisposable
的诊断警告,并且已被注册为瞬态。我可以处理这个——处理是在正确的地方处理的——但让我困惑的是,它绝对是而不是被注册为瞬态,因为我使用的是RegisterSingleton()
。
这是使用RegisterSingleton()
与创建lambda而不是实例的怪癖吗?是bug吗?还是我错过了我该做的事?
发生这种情况的最有可能的原因是您在代码的某个地方进行了以下调用:
container.GetInstance<SQLiteDataAccessProvider>();
或者您有一个依赖于此具体类型而不是抽象类型的构造函数(在这种情况下,您也可以预期有关此的其他警告)。
由于SQLiteDataAccessProvider
没有注册为"自身"(而只是通过IDataAccessProvider
的抽象),简单注入器将为你解析该类型,默认情况下,简单注入器将使该类型为瞬态。
通过这样做,一个新的注册被添加到简单注入器;您将能够在调试器中看到它。IDataAccessProvider
有单例注册,SQLiteDataAccessProvider
有瞬态注册。
现在,因为SQLiteDataAccessProvider
有一个瞬态注册,简单注入器会警告你这个实例不会被自动处理。
解决方案是删除GetInstance<SQLiteDataAccessProvider>()
调用(或更改ctor参数以使用抽象)并将其替换为对GetInstance<IDataAccessProvider>()
的调用。