如何确定在解析时Autofac使用哪个构造函数 [英] How to determine which constructor Autofac uses when resolving

查看:209
本文介绍了如何确定在解析时Autofac使用哪个构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using a custom JsonConverter and JsonSerializerSettings.TypeNameHandling = TypeNameHandling.Objects to create the required instances during deserialization. The instances are created by resolving the types from an Autofac IOC container. Everything works fine, except...

我有几个核心对象",它们从服务(正确注入到构造函数中)中请求构造函数中的唯一ID.反序列化时,这应该不会发生,因为它相当昂贵,并且一旦创建了实例,无论如何都会从Json文件填充ID.

I have several "core objects" that request a unique Id in the constructor from a service (which is correctly injected into the constructor). When deserializing this should not happen because it is fairly expensive and the Ids will be populated from the Json file anyway once the instance has been created.

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

Currently, when resolving from within the custom JsonConverter I'm using _scope.Resolve<T>(new TypedParameter(typeof(IIdService), null)); to then - in the called constructor - check for null and act accordingly.

有些人显然在使用IOC时认为多个构造函数比代码构造函数差(这使我想知道为什么Autofac为什么提供与该主题相关的多个功能),但是在反序列化的背景下,我认为这很有意义.

Some people apparently consider multiple constructors worse than a code-smell when using an IOC (which makes me wonder why Autofac offers several features regarding the topic), but in the context of deserialization I think it can make perfect sense.

据我所知,Autofac具有确定在注册期间使用哪个构造函数的机制,但不能决定解析期间使用的构造函数.我的首选解决方案是将自定义属性添加到构造函数(例如[CtorForDeserializing]),然后使用该属性进行决策.有可能吗?

As far as I can tell Autofac has mechanisms to decide which constructor to use during registration, but not when resolving. My preferred solution would be to add a custom attribute to a constructor (e.g. [CtorForDeserializing]) and use that for deciding. Is that possible?

推荐答案

Autofac有几个扩展点,可以用于基于反射的激活,但是还没有充分记录的扩展点,可能会对您有所帮助:IConstructorFinderIConstructorSelector.

There are a couple of extension points Autofac has for reflection-based activations but doesn't have well documented yet that may help you out: IConstructorFinder and IConstructorSelector.

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

IConstructorFinder is used to locate all the available constructors on a type. The core example is the DefaultConstructorFinder which locates only public constructors. If you wanted to, say, hide constructors with particular attributes or start finding internal/private constructors, you could create a custom finder. This really only happens once so you don't get to make runtime choices here.

IConstructorSelector用于在解析时选择应使用哪个构造函数来实例化对象.核心Autofac中有两个,但主要示例是

IConstructorSelector is used to choose, at resolve time, which constructor should be used to instantiate the object. There are a couple of these in core Autofac, but the primary example is the MostParametersConstructorSelector which selects the constructor that has the most available matching parameters at the time. Constructors get found by the IConstructorFinder and then that set of constructors is what is presented to the IConstructorSelector to choose from. This is where you could make more runtime choices since it happens every time the object is resolved.

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

There are extension methods to help you add your finder/selector to a registration:

builder.RegisterType<MyType>()
       .FindConstructorsWith(new MyConstructorFinder())
       .UsingConstructor(new MyConstructorSelector());

您不必自定义这两项,也可以只做其中一项.我只是向您展示扩展程序.

You don't have to customize both things, you can just do one or the other if you want. I'm just showing you the extensions.

这篇关于如何确定在解析时Autofac使用哪个构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆