ASP.NET Core 3.1系列(24)——依赖注入框架之Autofac

32 篇文章 43 订阅

1、前言

前面的博客已经介绍过ASP.NET Core中内置IoC容器的使用方法。对于规模较小的项目来说,内置容器完全够用。但在实际开发业务中,一般更推荐开发者使用Autofac作为系统的IoC容器。相较于微软提供的内置容器,Autofac无论是在功能性还是灵活性上都更胜一筹,下面开始介绍它的使用方法。

2、创建接口和类

本文通过控制台程序进行演示。使用NuGet引入如下组件:

Autofac

在这里插入图片描述
创建一个IAnimal接口,代码如下:

namespace App
{
    public interface IAnimal
    {
        string GetMsg();
    }
}

创建Cat类实现IAnimal接口,代码如下:

namespace App
{
    public class Cat : IAnimal
    {
        public string GetMsg()
        {
            return "This is cat";
        }
    }
}

创建Dog类实现IAnimal接口,代码如下:

namespace App
{
    public class Dog : IAnimal
    {
        public string GetMsg()
        {
            return "This is dog";
        }
    }
}

3、Autofac基本注册方法

Autofac中包含两个关键类:ContainerBuilderIContainer。其中ContainerBuilder是一个规则构建器,主要负责类和接口的注册。IContainer相当于容器,主要通过Resolve方法提供开发者需要的对象实例。它们的实例化方式如下所示:

using Autofac;

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            ContainerBuilder builder = new ContainerBuilder();
            IContainer container = builder.Build();
        }
    }
}

3.1、Register注册

Autofac中的Register方法可对类和接口进行注册,下面就来注册一下IAnimal接口和Cat类,代码如下:

using Autofac;
using System;

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 注册接口和类
            ContainerBuilder builder = new ContainerBuilder();
            builder.Register(p => new Cat()).As<IAnimal>();

            // 构建容器
            IContainer container = builder.Build();

            // 创建IAnimal实例
            IAnimal animal = container.Resolve<IAnimal>();
            Console.WriteLine(animal.GetMsg());
        }
    }
}

运行结果如下所示:

This is cat

3.2、RegisterType注册

Autofac中也可以使用RegisterType方法注册类接口和类,代码如下:

using Autofac;
using System;

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 注册接口和类
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterType<Cat>().As<IAnimal>();

            // 构建容器
            IContainer container = builder.Build();

            // 创建IAnimal实例
            IAnimal animal = container.Resolve<IAnimal>();
            Console.WriteLine(animal.GetMsg());
        }
    }
}

运行结果如下所示:

This is cat

3.3、RegisterInstance注册

Autofac提供了一个RegisterInstance方法,该方法支持实例注册,代码如下:

using Autofac;
using System;

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 注册接口和类
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterInstance(new Cat()).As<IAnimal>();

            // 构建容器
            IContainer container = builder.Build();

            // 创建IAnimal实例
            IAnimal animal = container.Resolve<IAnimal>();
            Console.WriteLine(animal.GetMsg());
        }
    }
}

运行结果如下所示:

This is cat

4、实例被覆盖的解决方法

一个接口可以有多个类来实现它。在上面的代码中,CatDog均实现了IAnimal接口。如果在Autofac中同时注册这两个类,则会引发实例覆盖问题,代码如下:

using Autofac;
using System;

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 注册接口和类
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterType<Cat>().As<IAnimal>();
            builder.RegisterType<Dog>().As<IAnimal>();

            // 构建容器
            IContainer container = builder.Build();

            // 创建IAnimal实例
            IAnimal animal = container.Resolve<IAnimal>();
            Console.WriteLine(animal.GetMsg());
        }
    }
}

运行结果如下所示:

This is dog

在上面的代码中,我们先注册了Cat,然后注册了Dog,此时Dog的实例就会覆盖Cat的实例。如果希望同时获取这两个类的实例,则可以使用NamedResolveNamed方法,代码如下:

using Autofac;
using System;

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 注册接口和类
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterType<Cat>().Named<IAnimal>("Cat");
            builder.RegisterType<Dog>().Named<IAnimal>("Dog");

            // 构建容器
            IContainer container = builder.Build();

            // 创建Cat实例
            IAnimal cat = container.ResolveNamed<IAnimal>("Cat");
            Console.WriteLine(cat.GetMsg());

            // 创建Dog实例
            IAnimal dog = container.ResolveNamed<IAnimal>("Dog");
            Console.WriteLine(dog.GetMsg());
        }
    }
}

运行结果如下所示:

This is cat
This is dog

5、Autofac模块的单独配置

在实际开发业务中,为了方便代码的管理,我们一般会单独建一个类来管理Autofac的模块。新建一个类IocModule,该类继承Autofac.Module,代码如下:

using Autofac;

namespace App
{
    public class IocModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<Cat>().Named<IAnimal>("Cat");
            builder.RegisterType<Dog>().Named<IAnimal>("Dog");
        }
    }
}

上面的代码重写了Load方法,我们可以在该方法中注册接口和类,最后在容器中加载IocModule 即可,代码如下:

using Autofac;
using System;

namespace App
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 注册接口和类
            ContainerBuilder builder = new ContainerBuilder();
            builder.RegisterModule(new IocModule());

            // 构建容器
            IContainer container = builder.Build();

            // 创建Cat实例
            IAnimal cat = container.ResolveNamed<IAnimal>("Cat");
            Console.WriteLine(cat.GetMsg());

            // 创建Dog实例
            IAnimal dog = container.ResolveNamed<IAnimal>("Dog");
            Console.WriteLine(dog.GetMsg());
        }
    }
}

运行结果如下所示:

This is cat
This is dog

6、结语

本文主要介绍了Autofac的基础使用方法。其实Autofac中还包含一些高效灵活的注册方法,例如程序集批量注册、泛型注册等等,合理使用这些方法能够极大地提升开发效率,后续博客会对这些方法进行逐一介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值