2015-08-28 37 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