Simple Injector 3 将注册视为瞬态,即使使用 `RegisterSingleton()`

Simple Injector 3 sees a registration as transient, even with `RegisterSingleton()`

我正在构建一个应用程序(Xamarin.Forms、PCL 和 iOS,如果它是相关的),它始终使用简单注入器进行依赖注入。到目前为止,使用它一直很棒,并且随着最近发布的 Simple Injector 3,我正在更新我的代码以使用新的 API。不幸的是,我在注册时遇到了一些问题。

基本流程如下:

然后应用程序可以使用数据访问提供程序在数据库上打开事务 - IDataAccessProvider 接口只有一个方法,NewTransaction(),它 return 是一个单位 -具有通用 CRUD 方法的工作对象。 IDataAccessProvider 还实现了 IDisposableDispose() 方法处理清理、关闭打开 connections/transactions 等

问题出在这些注册上:

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

出于某种原因,在启动时我得到 diagnostic warning SQLiteDataAccessProviderIDisposable 并且已注册为瞬态。我可以处理这个 - 处置在正确的地方处理 - 但让我困惑的是它肯定 而不是 被注册为瞬态,因为我正在使用 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>().

的调用