SimpleInjector.ActivationException由于收集生活方式

时间:2016-04-18 14:03:55

标签: c# simple-injector

我正在尝试将我的DI容器从Unity切换到SimpleInjector,而我正在努力收集。

我有IExceptionLogWriter的两个具体实现,我想注册为单身人士,所以我会做以下事情:

container.RegisterSingleton<RaygunExceptionLogWriter>();
container.RegisterSingleton<SqlExceptionLogWriter>();

现在我想注册两个集合,所以我这样做:

container
.RegisterCollection<IExceptionLogWriter>(
    new[] { 
        typeof(RaygunExceptionLogWriter), 
        typeof(SqlExceptionLogWriter) });

现在,当我尝试运行应用程序时,出现以下错误:

  

其他信息:遇到生活方式不匹配。 ExceptionLogger(Singleton)依赖于IExceptionLogWriter [](Transient)。生活方式不匹配会导致应用程序出现并发错误。请参阅https://simpleinjector.org/dialm以了解此问题以及解决方法。

如果我正确理解错误,我似乎需要以某种方式将IExceptionLogWriter[]注册为单身,因为我将RaygunExceptionLogWriterSqlExceptionLogWriter注册为单身人士。也许我是在密集,但我不能为我的生活弄清楚如何做到这一点。

我试过了:

container.RegisterSingleton<IExceptionLogWriter[]>();

这显然已经崩溃并烧毁。

修改 - 所有相关注册

container.RegisterSingleton<SqlConnectionFactory>(new SqlConnectionFactory(connectionString));
container.RegisterSingleton<IApplicationExceptionRepository, SqlApplicationExceptionRepository>();
container.RegisterSingleton<IErrorHandler, ErrorHandler>();
container.RegisterSingleton<IExceptionLogger, ExceptionLogger>();
container.RegisterSingleton<RaygunExceptionLogWriter>();
container.RegisterSingleton<SqlExceptionLogWriter>();
container
.RegisterCollection<IExceptionLogWriter>(
    new[] { 
        typeof(RaygunExceptionLogWriter), 
        typeof(SqlExceptionLogWriter) });

相关的构造函数:

public SqlConnectionFactory(string connectionString)
public SqlApplicationExceptionRepository(SqlConnectionFactory connectionFactory)
public ErrorHandler(IExceptionLogger exceptionLogger)
public ExceptionLogger(IExceptionLogWriter[] exceptionLogWriters)
public RaygunExceptionLogWriter()
public SqlExceptionLogWriter(IApplicationExceptionRepository applicationExceptionRepository)

1 个答案:

答案 0 :(得分:2)

这里发生的是您的ExceptionLogger组件具有类型为IExceptionLogWriter[]的构造函数参数(IExceptionLogWriter数组)。 Simple Injector会自动为您解析数组,但Simple Injector进行的隐式注册是暂时的。原因是:

  • 数组是引用列表。如果列表包含瞬态组件,则将数组作为单例注入将导致Captive Dependencies
  • 数组是一种可变类型;每个人都可以改变数组的内容。将其设为单例可能会导致应用程序的不相关部分因阵列更改而失败。

因此,出于安全原因,Simple Injector使阵列注册成为瞬态。这允许诊断系统启动并警告您可能导致的任何强制依赖。

解决方案很简单,您有两种选择:

  1. 使ExceptionLogger消费者瞬态,或
  2. ExceptionLogger的依赖关系从IExceptionLogger[]更改为IEnumerable<IExceptionLogger>IList<IExceptionLogger>ICollection<IExceptionLogger>IReadOnlyList<IExceptionLogger>IReadOnlyCollection<IExceptionLogger>
  3. 对于这些集合抽象,Simple Injector将注入一个集合:

    • 无法从外部更改,
    • 每次重复收集时,通过根据其生活方式解析元素来防止强制依赖。
相关问题