Autofac无参数构造函数选择

时间:2012-12-21 10:22:08

标签: autofac

“Autofac会自动选择能够从容器中获取的参数最多的构造函数。”我希望它不这样做,而是选择默认构造函数。 http://code.google.com/p/autofac/wiki/Autowiring

internal class ParameterlessConstructorSelector : IConstructorSelector
{
    #region Implementation of IConstructorSelector

    /// <summary>
    /// Selects the best constructor from the available constructors.
    /// </summary>
    /// <param name="constructorBindings">Available constructors.</param>
    /// <returns>
    /// The best constructor.
    /// </returns>
    public ConstructorParameterBinding SelectConstructorBinding(ConstructorParameterBinding[] constructorBindings)
    {
        return constructorBindings.First();
    }

    #endregion
}

当我上课时,我这样做了:

builder.RegisterType<EmployeeFactory>()
       .As<IEmployeeFactory>().UsingConstructor(new ParameterlessConstructorSelector())
       .SingleInstance();

constructorBindings列表中的第一个绑定始终是带有paremeterless构造函数的绑定。不确定它是先定义还是autofac扫描构造函数的方式,但这是无参数构造函数的正确接线方法吗?

由于

3 个答案:

答案 0 :(得分:7)

Autofac在内部使用Type.GetConstructors方法来发现构造函数。

从方法documentation

  

GetConstructors方法不返回a中的构造函数   特定订单,例如声明订单。您的代码不得依赖   返回构造函数的顺序,因为该顺序   而变化。

因此,在您的情况下,它与First()一起运行只是运气。在正确的实现中,您需要显式搜索带有0参数的构造函数:

public class DefaultConstructorSelector : IConstructorSelector
{
    public ConstructorParameterBinding SelectConstructorBinding(
        ConstructorParameterBinding[] constructorBindings)
    {
        var defaultConstructor = constructorBindings
          .SingleOrDefault(c => c.TargetConstructor.GetParameters().Length == 0);
        if (defaultConstructor == null)
            //handle the case when there is no default constructor
            throw new InvalidOperationException();                
        return defaultConstructor;
    }
}

你可以用这个非常简单的类测试理论:

public class MyClass
{
    public readonly int i;

    public MyClass(int i)
    {
        this.i = i;
    }

    public MyClass()
    {
        i = 1;
    }
}

通过实施:

var builder = new ContainerBuilder();
// register 22 for each integer constructor argument
builder.Register<int>(v => 22); 

builder.RegisterType<MyClass>().AsSelf()
    .UsingConstructor(new ParameterlessConstructorSelector());
var c = builder.Build();
var myClass = c.Resolve<MyClass>();
Console.WriteLine(myClass.i);

它输出22,例如,带有int参数的构造函数被称为:

通过我的实施:

//...
builder.RegisterType<MyClass>().AsSelf()
    .UsingConstructor(new DefaultConstructorSelector());
//...
var myClass = c.Resolve<MyClass>();
Console.WriteLine(myClass.i);

它输出1,例如调用默认构造函数。

答案 1 :(得分:1)

只是显式注册默认构造函数不是更简单吗?

builder.Register<EmployeeFactory>(c => new EmployeeFactory())
   .As<IEmployeeFactory>()
   .SingleInstance();

答案 2 :(得分:1)

使用最新版本的Autofac,这非常简单:

string mystring::strreturn(string s1)
{
char *p,arr[9];
char *c=new char[s1.size()+1];
copy(s1.begin(),s1.end(),c);
c[s1.size()]='\0';
p=rtstr(c);
strcpy(arr,p);
st=arr;
return st;
}

Calling&#34; UsingConstructor&#34;没有参数意味着&#34;使用无参数构造函数&#34;。 请参阅https://autofac.org/apidoc/html/EB67DEC4.htm及相关页面。