Simple Injector 3 将注册视为瞬态,即使使用 `RegisterSingleton()`
Simple Injector 3 sees a registration as transient, even with `RegisterSingleton()`
我正在构建一个应用程序(Xamarin.Forms、PCL 和 iOS,如果它是相关的),它始终使用简单注入器进行依赖注入。到目前为止,使用它一直很棒,并且随着最近发布的 Simple Injector 3,我正在更新我的代码以使用新的 API。不幸的是,我在注册时遇到了一些问题。
基本流程如下:
- 注册一个
ISQLitePlatform
(Windows、iOS、Android 等)来处理特定于平台的位(SQLite API、文件 I/O等)
- 注册一个引导程序,它将负责创建数据库文件、设置所有 table/type 映射等
- 注册一个将创建我们的数据访问提供程序的 lambda,使用引导程序设置数据库,return 访问提供程序
然后应用程序可以使用数据访问提供程序在数据库上打开事务 - IDataAccessProvider
接口只有一个方法,NewTransaction()
,它 return 是一个单位 -具有通用 CRUD 方法的工作对象。 IDataAccessProvider
还实现了 IDisposable
,Dispose()
方法处理清理、关闭打开 connections/transactions 等
问题出在这些注册上:
container.RegisterSingleton<ISQLitePlatform, SQLitePlatformIOS>();
container.RegisterSingleton<ILocalDataBootstrapper, SQLiteDataBootstrapper>();
container.RegisterSingleton<IDataAccessProvider>(
() => container.GetInstance<ILocalDataBootstrapper>().DataAccessProvider);
出于某种原因,在启动时我得到 diagnostic warning SQLiteDataAccessProvider
是 IDisposable
并且已注册为瞬态。我可以处理这个 - 处置在正确的地方处理 - 但让我困惑的是它肯定 而不是 被注册为瞬态,因为我正在使用 RegisterSingleton()
.
这是将 RegisterSingleton()
与创建 lambda 而不是实例一起使用的怪癖吗?这是一个错误吗?还是我错过了我应该做的事情?
发生这种情况的最可能原因是您在代码中的某处进行了以下调用:
container.GetInstance<SQLiteDataAccessProvider>();
或者你有一个依赖于这个具体类型而不是抽象的构造函数(在这种情况下你也可以期待关于这个的其他警告)。
由于 SQLiteDataAccessProvider
未注册 'as itself'(而仅通过其 IDataAccessProvider
抽象),Simple Injector 将为您解析此类型,默认情况下 Simple Injector 将使此类型成为瞬态.
这样,Simple Injector 就添加了一个新的注册;您将能够在调试器中看到它。 IDataAccessProvider
有单例注册,SQLiteDataAccessProvider
有瞬时注册。
现在因为 SQLiteDataAccessProvider
有一个临时注册,Simple Injector 会警告你这个实例不会被自动释放。
解决方案是删除 GetInstance<SQLiteDataAccessProvider>()
调用(或更改 ctor 参数以使用抽象)并将其替换为对 GetInstance<IDataAccessProvider>()
.
的调用
我正在构建一个应用程序(Xamarin.Forms、PCL 和 iOS,如果它是相关的),它始终使用简单注入器进行依赖注入。到目前为止,使用它一直很棒,并且随着最近发布的 Simple Injector 3,我正在更新我的代码以使用新的 API。不幸的是,我在注册时遇到了一些问题。
基本流程如下:
- 注册一个
ISQLitePlatform
(Windows、iOS、Android 等)来处理特定于平台的位(SQLite API、文件 I/O等) - 注册一个引导程序,它将负责创建数据库文件、设置所有 table/type 映射等
- 注册一个将创建我们的数据访问提供程序的 lambda,使用引导程序设置数据库,return 访问提供程序
然后应用程序可以使用数据访问提供程序在数据库上打开事务 - IDataAccessProvider
接口只有一个方法,NewTransaction()
,它 return 是一个单位 -具有通用 CRUD 方法的工作对象。 IDataAccessProvider
还实现了 IDisposable
,Dispose()
方法处理清理、关闭打开 connections/transactions 等
问题出在这些注册上:
container.RegisterSingleton<ISQLitePlatform, SQLitePlatformIOS>();
container.RegisterSingleton<ILocalDataBootstrapper, SQLiteDataBootstrapper>();
container.RegisterSingleton<IDataAccessProvider>(
() => container.GetInstance<ILocalDataBootstrapper>().DataAccessProvider);
出于某种原因,在启动时我得到 diagnostic warning SQLiteDataAccessProvider
是 IDisposable
并且已注册为瞬态。我可以处理这个 - 处置在正确的地方处理 - 但让我困惑的是它肯定 而不是 被注册为瞬态,因为我正在使用 RegisterSingleton()
.
这是将 RegisterSingleton()
与创建 lambda 而不是实例一起使用的怪癖吗?这是一个错误吗?还是我错过了我应该做的事情?
发生这种情况的最可能原因是您在代码中的某处进行了以下调用:
container.GetInstance<SQLiteDataAccessProvider>();
或者你有一个依赖于这个具体类型而不是抽象的构造函数(在这种情况下你也可以期待关于这个的其他警告)。
由于 SQLiteDataAccessProvider
未注册 'as itself'(而仅通过其 IDataAccessProvider
抽象),Simple Injector 将为您解析此类型,默认情况下 Simple Injector 将使此类型成为瞬态.
这样,Simple Injector 就添加了一个新的注册;您将能够在调试器中看到它。 IDataAccessProvider
有单例注册,SQLiteDataAccessProvider
有瞬时注册。
现在因为 SQLiteDataAccessProvider
有一个临时注册,Simple Injector 会警告你这个实例不会被自动释放。
解决方案是删除 GetInstance<SQLiteDataAccessProvider>()
调用(或更改 ctor 参数以使用抽象)并将其替换为对 GetInstance<IDataAccessProvider>()
.