配置 autofac 以忽略标记为过时的构造函数
是否可以轻松配置 autofac,使其仅使用非过时的构造函数进行解析?
例如,对于具有非 DI 代码的辅助构造函数的类,
public class Example {
public Example(MyService service) {
// ...
}
[Obsolete]
public Example() {
service = GetFromServiceLocator<MyService>();
// ...
}
}
// ....
var builder = new ContainerBuilder();
builder.RegisterType<Example>();
// no MyService defined.
var container = builder.Build();
// this should throw an exception
var example = container.Resolve<Example>();
如果我们尚未注册 MyService,则要求 autofac 解析 Example 应该会失败。
Is it possible to easily configure autofac so it will only resolve using non-obsolete constructors?
eg for a class with a helper constructor for non-DI code,
public class Example {
public Example(MyService service) {
// ...
}
[Obsolete]
public Example() {
service = GetFromServiceLocator<MyService>();
// ...
}
}
// ....
var builder = new ContainerBuilder();
builder.RegisterType<Example>();
// no MyService defined.
var container = builder.Build();
// this should throw an exception
var example = container.Resolve<Example>();
asking autofac to resolve Example if we haven't registered MyService, should fail.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不相信有一种开箱即用的方法来配置 Autofac 来忽略过时的构造函数。但是,Autofac 非常好,总有办法完成它:) 这里有两个选项:
选项 1. 告诉 Autofac 使用哪个构造函数
使用
UsingConstructor
注册扩展方法。选项 2. 向
FindConstructorsWith
提供自定义IConstructorFinder
Autofac 有一个名为
FindConstructorsWith
的注册扩展方法。您可以将自定义IConstructorFinder
传递给两个重载之一。您可以编写一个名为NonObsoleteConstructorFinder
的简单IConstructorFinder
,它只会返回不带 Obsolete 属性的构造函数。我已经编写了这个课程并添加了您的示例的工作版本。您可以查看完整代码并将其用作灵感。 IMO 选项,这是更优雅的选项。我已将其添加到 GitHub 上的 AutofacAnswers 项目中。
注意:另一个重载采用 BindingFlags。我认为您无法使用
BindingFlags
指定属性要求。不过,您可能想检查一下。I don't believe there is an out of the box way to configure Autofac to ignore
Obsolete
constructors. However, Autofac is so good, there is always a way to get it done :) Here are two options:Option 1. Tell Autofac which Constructor to use
Do this using the
UsingConstructor
registration extension method.Option 2. Provide a custom
IConstructorFinder
toFindConstructorsWith
Autofac has a registration extension method called
FindConstructorsWith
. You can pass a customIConstructorFinder
to one of the two overloads. You could write a simpleIConstructorFinder
calledNonObsoleteConstructorFinder
that will only return constructors without the Obsolete attribute.I have written this class and added a working version of your sample. You can view the full code and use it as inspiration. IMO option this is the more elegant option. I have added it to my AutofacAnswers project on GitHub.
Note: The other overload takes BindingFlags. I don't think you can specify attribute requirements using
BindingFlags
. However, you may want to check that.这是 Bentayloruk 答案的延伸。我尝试了他的选项 2,但没有成功。很快我注意到这是因为我使用了 AutoFac 拦截器。 AutoFac 将代理类类型传递给构造函数查找器,但这些构造函数没有在基础类的构造函数上定义的属性。
为了完成这项工作,我的代码会比较两个类的构造函数签名,以找到“正确的”构造函数并检查该属性是否存在。
注释 1:
Skip(1)
是必需的,因为代理的第一个构造函数参数的类型为IInterceptor[]
。 AutoFac 使用它来传递拦截器。注2:
targetType.Implements()
和underlyingConstructor.HasAttribute()
是 Fasterflect 库提供的扩展方法。This is an extension to bentayloruk's answer. I tried his Option 2 but it didn't work. Soon I noticed that this is because I'm using AutoFac Interceptors. AutoFac passes the proxy class type to the constructor finder but these constructors don't have the attributes defined on the constructors in the underlying class.
To make this work my code compares the constructor signatures of both classes to find the "correct" constructor and checks if the attribute is present.
Note 1:
Skip(1)
is required because the first constructor argument of the proxy is of typeIInterceptor[]
. This is used by AutoFac to pass the interceptors.Note 2:
targetType.Implements<IProxyTargetAccessor>()
andunderlyingConstructor.HasAttribute<ObsoleteAttribute>()
are extension methods provided by the Fasterflect library.