如果我有以下类,是否可以从Autofac注册中排除复制构造函数?
public class A
{
public A() {}
public A(A other) { // copy constructor }
public A(int b) { // some other stuff }
}
基本上,我希望autofac解析默认构造函数,或者如果用户请求Func<int, A>
第三个构造函数。我从不希望autofac解析复制构造函数。这可能吗?
原因是当我尝试使用Autofac注入Func<A>
时,它会导致循环依赖,因为Autofac正在尝试使用第二个构造函数(它认为它知道解决A的方法,但解决A的方法需要A)。
答案 0 :(得分:3)
您可以实现自己的忽略第二个构造函数的constructor selector:
public class AConstructorSelector : IConstructorSelector
{
public ConstructorParameterBinding SelectConstructorBinding(ConstructorParameterBinding[] constructorBindings)
{
if (constructorBindings == null) throw new ArgumentNullException("constructorBindings");
if (constructorBindings.Length == 0) throw new ArgumentOutOfRangeException("constructorBindings");
if (constructorBindings.Length == 1)
return constructorBindings[0];
var withLength = constructorBindings
.Where(b => !b.TargetConstructor.GetParameters().Select(p => p.ParameterType).Contains(typeof(A)))
.Select(binding => new { Binding = binding, ConstructorParameterLength = binding.TargetConstructor.GetParameters().Length })
.ToArray();
var maxLength = withLength.Max(binding => binding.ConstructorParameterLength);
var maximal = withLength
.Where(binding => binding.ConstructorParameterLength == maxLength)
.Select(ctor => ctor.Binding)
.ToArray();
if (maximal.Length == 1)
return maximal[0];
throw new DependencyResolutionException("Unable to find constructor");
}
}
注册课程时,请将其用作UsingConstructor
var builder = new ContainerBuilder();
builder.RegisterType<A>().UsingConstructor(new AConstructorSelector());
请参阅fiddle
答案 1 :(得分:1)
Autofac 3.x会自动创建Implicit Relationship Types,例如Func<A>
,Lazy<B>
等。但您可以通过注册自己来覆盖默认值。
builder.Register<Func<int, A>>(c => (value) => { return new A(value); });
这是注册Func<int, A>
签名并指示使用哪个构造函数来创建它。
在.NET Fiddle上试用,https://dotnetfiddle.net/CTFyo3