如何确定 Autofac 在解析时使用哪个构造函数

mik*_*ike 4 c# autofac json.net deserialization

我正在使用自定义 JsonConverter 并JsonSerializerSettings.TypeNameHandling = TypeNameHandling.Objects在反序列化期间创建所需的实例。这些实例是通过解析 Autofac IOC 容器中的类型来创建的。一切都很好,除了......

我有几个“核心对象”,它们在服务的构造函数中请求唯一的 ID(已正确注入到构造函数中)。反序列化时不应发生这种情况,因为它相当昂贵,并且一旦创建实例,ID 就会从 Json 文件填充。

目前,当从自定义 JsonConverter 中解析时,我使用_scope.Resolve<T>(new TypedParameter(typeof(IIdService), null));- 在被调用的构造函数中 - 检查 null 并采取相应的行动。

有些人显然认为使用 IOC 时多个构造函数比代码味道更糟糕(这让我想知道为什么 Autofac 提供了与该主题相关的多个功能),但在反序列化的背景下,我认为它非常有意义。

据我所知,Autofac 有机制来决定在注册期间使用哪个构造函数,但在解析时则不然。我的首选解决方案是将自定义属性添加到构造函数(例如[CtorForDeserializing])并使用它来做出决定。那可能吗?

Tra*_*lig 6

Autofac 有几个用于基于反射的激活的扩展点,但尚未有详细记录,可以帮助您:IConstructorFinderIConstructorSelector

IConstructorFinder用于定位类型上所有可用的构造函数。核心示例是DefaultConstructorFinder仅定位公共构造函数。例如,如果您想隐藏具有特定属性的构造函数或开始查找内部/私有构造函数,您可以创建一个自定义查找器。这实际上只发生一次,因此您无需在此处进行运行时选择。

IConstructorSelector用于在解析时选择应使用哪个构造函数来实例化对象。Autofac 核心中有几个这样的例子,但主要的例子是MostParametersConstructorSelector选择当时具有最多可用匹配参数的构造函数。构造函数由 找到IConstructorFinder,然后该组构造函数将提供给 进行IConstructorSelector选择。您可以在此处做出更多运行时选择,因为每次解析对象时都会发生这种情况。

有一些扩展方法可以帮助您将查找器/选择器添加到注册中:

builder.RegisterType<MyType>()
       .FindConstructorsWith(new MyConstructorFinder())
       .UsingConstructor(new MyConstructorSelector());
Run Code Online (Sandbox Code Playgroud)

您不必自定义这两件事,如果您愿意,您可以只做其中之一。我只是向您展示扩展。