Autofac入门之解析获取

本次主要学习如何在Autofac中解析注册类型实例

使用Resolve方法获取容器中注册的类型实例,如果类型未注册会抛异常 

 var sqlDal = container.Resolve<SqlDal>();
     sqlDal.Add();

使用ResolveOptional方法获取容器中注册的类型实例,如果类型未注册会返回null

var sqlDal2 = container.ResolveOptional<SqlDal>();
    sqlDal2.Add();

使用TryResolve方法获取容器中注册的类型实例,使用out参数,并且返回一个bool类型表示是否成功获取到类型实例

SqlDal sqlDal3 = null;
if (container.TryResolve<SqlDal>(out sqlDal3))
    sqlDal3.Add();
else
    Console.WriteLine("类型未注册");

Resolve对象构造方法选择原则(当我们注册的类型拥有多个构造方法,那么在Resolve时,将会以尽可能最多参数构造方法为准)

class ConstructorClass
{
    private Class1 _clas1;
    private Class2 _clas2;
    private Class3 _clas3 = null;

    public ConstructorClass()
    {
        _clas1 = null; _clas2 = new Class2 { Id = -1 };
    }

    public ConstructorClass(Class1 clas1, Class2 clas2)
    {
        _clas1 = clas1; _clas2 = clas2;
    }

    public ConstructorClass(Class2 clas2, Class3 clas3)
    {
        _clas2 = clas2; _clas3 = clas3;
    }

    public ConstructorClass(Class2 clas2, Class3 clas3, Guid guid)
    {
        _clas1 = new Class1 { Id = guid }; _clas2 = clas2; _clas3 = clas3;
    }

    public ConstructorClass(Class1 clas1, Class2 clas2, Class3 clas3)
    {
        _clas1 = clas1; _clas2 = clas2; _clas3 = clas3;
    }

    public override string ToString()
    {
        return string.Format(
            "{{Class1.Id: {0}, Class2.Id: {1}, Class3: {2}}}",
            _clas1 == null ? "null" : _clas1.Id.ToString(),
            _clas2 == null ? "null" : _clas2.Id.ToString(),
            _clas3 == null ? "null" : "not null");
    }
}

class Class1
{
    public Guid Id { get; set; }
}

class Class2
{
    public int Id { get; set; }
}

class Class3
{

}
var builder = new ContainerBuilder();    
builder.RegisterType<ConstructorClass>();
builder.RegisterType<Class2>();
builder.RegisterType<Class3>();
var obj = container.Resolve<ConstructorClass>();
Console.WriteLine(obj); 

按照字面上里说明”最多参数“,那么理应执行的是最后一个构造方法或倒数第二个构造方法,但是为什么却是第三个?

先抛开为什么执行的第三个构造方法,我们还是会有疑问”如果执行的是第三个构造方法,那么Class2和Class3参数分别赋的是什么值?值又是从哪儿来?“,这里就涉及到了后面会讲到的构造注入。我们可以看到,在进行类型注册时,我们是对Class2和Class3进行了注册的,而ConstructorClass又是通过Autofac进行获取的,所以Class2和Class3参数的值是由Autofac进行初始化赋值的,Class2和Class3没有自定义构造方法,所以调用的是默认的空构造方法。

在知道Class2和Class3参数的初始化与赋值缘由后,我们再来看看之前的那个问题,为什么会执行第三个构造方法,其实现在就好明白了,因为最后两个的构造方法,一个需要额外的Guid类型参数,另一个需要Class1类型参数,而这两个类型又没有经过注册,如果调用这两个构造方法,那么Auotofac将不知道应该赋何值给这两个参数,所以Autofac最终选择了第三个构造方法

第二个构造函数和第三个构造函数参数个数相同,为什么不选择第二个而是选择了第三个构造函数呢?

最后这段话说明了原因,在当前例子中:解析组件时发现Class2和Class3已被注册,而在构造函数中第二个构造函数(Class1 clas1, Class2 clas2)只找到了Class2,Class1并没有在Autofac中注册,而(Class2 clas2, Class3 clas3)中找到了两个,所以选择了第三个构造函数

这里发现一个问题,我将第三个构造函数注释后发现,Autofac会调用默认创建无参构造函数,按照上面的逻辑,因为Class2是已经在Autofac中注册的,此时不应该调用第二个构造函数吗?

TODO:这里理解的不是很透彻,随后需要再学习一下

猜你喜欢

转载自www.cnblogs.com/GnailGnepGnaw/p/10747629.html