Autofac - 组件

快到年终了, 最近项目比较悠闲, 就想总结下, 项目中所使用到的一些技术, 以及使用方法.

之前有写过Dapper以及Dapper的一个扩展, 这些也是项目中使用过的. 算是一个温故而知新吧.

代码:

public interface IAnimal
{
    void Say();
}

public class Dog : IAnimal
{
    public string Name { get; set; }
    public void Say()
    {
        Console.WriteLine("汪汪汪!");
        if (!string.IsNullOrEmpty(Name))
        {
            Console.WriteLine("此汪名叫 " + Name);
        }
    }
}

public class Cat : IAnimal
{
    public string Name { get; set; }
    public void Say()
    {
        Console.WriteLine("喵喵喵!");
        if (!string.IsNullOrEmpty(Name))
        {
            Console.WriteLine("此喵名叫 " + Name);
        }
    }
}

public class Person
{
    IAnimal adopt;

    public Person()  { }

    public void Self()
    {
        Console.WriteLine("我是主人");
    }

    public Person(IAnimal MyPerson)
    {
        adopt = MyPerson;
    }

    public void Say()
    {
        Console.WriteLine("我领养了一只小动物");
        adopt.Say();
    }
}

 

 一、类型注册

类型的注册, 使用的方法是container.Resolve<Type>()和container.Resolve(typeof(Type))两个方法.

示例:

var builder = new ContainerBuilder();

builder.RegisterType<Person>();
builder.RegisterType<Dog>().As<IAnimal>();
builder.RegisterType(typeof(Cat));

var container =  builder.Build();

var person = container.Resolve<Person>();
person.Self();
Console.WriteLine("---------");
var animal = container.Resolve<IAnimal>();
animal.Say();
Console.WriteLine("---------");
var cat = container.Resolve<Cat>();
cat.Say();

从图上可以看出, 通过这种方式注册类型之后, 可以正常获取到实例

 

二、实例注册

示例: (共同部分我就不贴了, 只贴主要部分)

builder.RegisterInstance(new Person(new Dog()));

//-------------------------------------------------
var person = container.Resolve<Person>();
person.Self();
person.Say();

这里还有一种为单例模式准备的实现, 可以把单例托管为容器单例, 我这里就没有写那么多了, 直接上了一个非单例的示例. 也是有效果的哟

builder.RegisterInstance(new Cat()).ExternallyOwned();

//-------------------------------------------------
var cat = container.Resolve<Cat>();
cat.Name = "miao";
cat.Say();

var cat1 = container.Resolve<Cat>();
cat1.Say();

这里我后来试了一下, 就算不加那个, 得到的效果也是单例的效果 

 

 三、Lambda方式注册 

//builder.RegisterType<Dog>().As<IAnimal>();
builder.Register(c => new Person(c.Resolve<IAnimal>()));
builder.RegisterType<Dog>().As<IAnimal>();

//-------------------------------------------------
var person = container.Resolve<Person>();
person.Say();

IAnimal注册的位置不受限制, 在前面, 在后面, 都是不受影响的, 但是不能没有啊, 没有就会报错了, 程序找不到.

 

四、程序集注册

这种方式适合懒人用

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();

//-------------------------------------------------
var animal = container.Resolve<IAnimal>();
animal.Say();

我这里面有两个类实现了IAnimal接口, 但是为什么这里获取到的是cat类, 而不是dog类呢?

 

五、泛型注册

builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>)).InstancePerLifetimeScope();
var container = builder.Build();
//-------------------------------------------------
IList<Dog> dogs = container.Resolve<IList<Dog>>();

这里获取到的dogs是一个空的集合, 并不是null值.

 

六、默认注册

如果一个类, 被多次注册, 会以最后一次注册为准, 就想上面 "四" 出现的情况, 只输出了"喵喵喵", 那是因为Dog类先注册, Cat类后注册, 把之前的覆盖掉了. 注意, 覆盖并不是没有了, 只是不能通过这种方式获取了而已, 还是可以通过别的方式来获取你想要的类的.

先看一下效果:

builder.RegisterType<Dog>().As<IAnimal>();
builder.RegisterType<Cat>().As<IAnimal>();

//-------------------------------------------------
var animal = container.Resolve<IAnimal>();
animal.Say();

如果我想要输出Dog类咋搞呢. 使用 PreserveExistingDefaults(), 这个方法是告诉容器, 这次注册的不是默认输出的.

builder.RegisterType<Dog>().As<IAnimal>();
builder.RegisterType<Cat>().As<IAnimal>().PreserveExistingDefaults();
//-------------------------------------------------
var animal = container.Resolve<IAnimal>();
animal.Say();

 那如果想一个接口上注册多个类, 并且都能正常获取呢? 那就看下一篇分解了

 参考资料:

Autofac 组件、服务、自动装配 《第二篇》

Autofac文档

posted @ 2016-12-13 11:21  Sniper_ZL  阅读(594)  评论(0)    收藏  举报