即使使用`RegisterSingleton()`,SimpleInjector 3也会将注册看作瞬态

时间:2015-08-28 13:31:11

标签: c# lifecycle simple-injector

我正在构建一个应用程序(Xamarin.Forms,PCL和iOS,以防它相关),它使用SimpleInjector进行依赖注入。到目前为止,它一直很好用,并且随着最近发布的SimpleInjector 3,我更新了我的代码以使用新的API。不幸的是,我在一次特定注册时遇到了一些麻烦。

以下是基本流程:

  • 注册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);

出于某种原因,在启动时,我得到SQLiteDataAccessProvider IDisposableRegisterSingleton()且已注册为瞬态的diagnostic warning。我可以处理这个 - 处理正在正确的地方处理 - 但让我感到困惑的是它肯定被注册为瞬态,因为我&#39; m使用RegisterSingleton()

这是使用IComm创建lambda而不是实例的怪癖吗?这是一个错误吗?或者我错过了我应该做的事情?

1 个答案:

答案 0 :(得分:3)

发生这种情况的最可能原因是您的代码中的某个位置会进行以下调用:

container.GetInstance<SQLiteDataAccessProvider>();

或者你有一个构造函数依赖于这个具体类型而不是抽象(在这种情况下你也可以期待关于这个的其他警告)。

由于SQLiteDataAccessProvider未注册&#39;本身&#39; (但仅仅通过其IDataAccessProvider抽象),Simple Injector将为您解析此类型,默认情况下,Simple Injector将使此类型成为瞬态。

通过这样做,新的注册被添加到Simple Injector;你将能够在调试器中看到它。 IDataAccessProvider有单身注册,SQLiteDataAccessProvider有临时注册。

现在因为SQLiteDataAccessProvider有临时注册,Simple Injector会警告您此实例不会自动处理。

解决方案是删除GetInstance<SQLiteDataAccessProvider>()调用(或使用抽象来改变ctor参数)并将其替换为GetInstance<IDataAccessProvider>()的调用。