C# Autofac:使用不同的构造函数将组件注册为不同的服务

C# Autofac:使用不同的构造函数将组件注册为不同的服务,c#,autofac,C#,Autofac,我想为多个服务注册一个单例组件,并根据解析调用期间使用的服务定义要使用的构造函数 我试过这个: _builder.RegisterType<TComponent>() .As<IService1>() .FindConstructorsWith(ConstructorFinder1) .SingleInstance(); _builder.RegisterType<TComponent>() .As<IService2&

我想为多个服务注册一个单例组件,并根据解析调用期间使用的服务定义要使用的构造函数

我试过这个:

_builder.RegisterType<TComponent>()
    .As<IService1>()
    .FindConstructorsWith(ConstructorFinder1)
    .SingleInstance();

_builder.RegisterType<TComponent>()
    .As<IService2>()
    .FindConstructorsWith(ConstructorFinder2)
    .SingleInstance();
\u builder.RegisterType()
.As()
.FindConstructorWith(ConstructorFinder1)
.SingleInstance();
_builder.RegisterType()
.As()
.FindConstructorWith(ConstructorFinder2)
.SingleInstance();
但这会导致两个不同的“单例”实例,具体取决于所使用的服务

所以我试着:

_builder.RegisterType<TComponent>()
    .As<IService1>()
    .FindConstructorsWith(ConstructorFinder1)
    .As<IService2>()
    .FindConstructorsWith(ConstructorFinder2)
    .SingleInstance();
\u builder.RegisterType()
.As()
.FindConstructorWith(ConstructorFinder1)
.As()
.FindConstructorWith(ConstructorFinder2)
.SingleInstance();
这解决了单例问题,但遗憾的是,第二个
FindConstructorsWith
调用覆盖了第一个调用,即对两个服务都使用
ConstructorFinder2

我曾假设(希望)ConstructorFinder将存储在服务中,但显然不是这样

我试图实现的是概念上的错误,是Autofac不支持它,还是我只是错过了什么

编辑: 再次感谢特拉维斯的出色回应。显然,我遗漏了一些让事情变得混乱的细节。现在让我补充一些

这个问题实际上是一种后续问题(特拉维斯也帮助了我)。因此,反序列化时会出现问题,它会影响许多不同的对象

我得到了关于组合、关注点分离以及拥有多个组件通常被认为是一种代码味道的争论,但在反序列化环境中(至少对于我目前开发的应用程序而言),能够以不同的方式创建实例是非常有用的,这取决于它们是新生成的还是从项目文件反序列化的。构建新实例时需要初始化的几个成员在反序列化时不必初始化(因为它们的值无论如何都会在反序列化过程中被重写)。这将意味着额外的性能成本和(在本例中)与一次性初始化相关的其他问题

在花了几天时间试图找到一个解决方案(Newtonsoft Json方面也出现了一些复杂问题)之后,我决定停止使用Autofac并实现我们自己的IOC容器。一般来说,它无法(显然!)以任何方式与Autofac竞争,但由于我们实际上只使用了Autofac强大功能的一小部分,我觉得我们可以尝试推出自己的功能。我花的时间比我花在一个整体式黑盒子上的时间要少得多。是的,Autofac是开源的,但是在代码中逐步执行不会在公园里散步

最初的测试非常有希望,重新获得对应用程序如此重要组件的完全控制感觉很好


同样,离开Autofac的原因是(可行的)不可能根据构造单例组件的服务来定义如何构造单例组件。从总体结构/概念的角度来看,我理解将服务和施工方式严格分开是有意义的。但是在反序列化过程中,我相信事情是不同的。现在我独立于Autofac,我可能会决定改变这些机制,使其更直接地融入整体概念。

这是一个很难回答的问题,因为你似乎有一些潜在的目标,你正试图实现,你有一个解决方案,你想工作,但可能是错误的解决方案,你应该问一个[新的]问题取决于这个回答对你的影响

让我来解释一下为什么很难回答这个问题

我想为多个服务注册一个单例组件,并根据解析调用期间使用的服务定义要使用的构造函数

如果是一个单子,那就意味着整个系统中都有一个单子,对吗?它实际上是“wins中的第一个”。如果某个东西将其解析为
IService1
,那么将调用与之关联的构造函数,即使您尝试将其解析为
IService2
,稍后也不会发生构造,因为创建了单例。反之亦然-
IService2
得到解析,构造函数路径在那里被遵循,然后要求
IService1
的东西将得到单例,并且不调用构造函数

这引起了一个关注:

  • 如果您知道首先要解决的是哪件事,那么为什么需要两个不同的构造函数选择器呢
  • 如果您不知道将首先解决哪件事,那么您是否要考虑系统的不可预测性
我以前见过这类问题,通常它们表明的是两件事之一:

  • 您正试图根据上下文进行某种选择或特殊逻辑。通常解决方法是重构。我马上就回来
  • 您正在尝试在两个不同的应用程序之间“共享注册”。答案是;但如果每种应用类型都有特殊注册,那就让它发生吧
  • 这并不是说这两个问题都是你想要的,但我在这里看到了这样的问题。通常会有一些潜在的目标,其中预先选择了一个解决方案,最好询问如何解决该目标,而不是如何实施一个非常具体的解决方案。再说一次,我可能错了

    在上面第1项的重构说明中,基于对单例的需求,我可以进一步猜测有某种资源需要共享,比如数据库连接,或者启动起来很昂贵。考虑将<代码> TStuts<代码>分成三个不同的类:

    • t常见费用组件
      -thi