.NET Core6.0环境下使用Autofac框架对webAPI进行依赖注入改造

1. 控制反转与依赖注入的优点

面向对象设计较之面向过程设计,在很大程度上使得代码与过程解耦,极大的提升了开发效率和增强了系统的可维护性,但对象之间的依赖与耦合仍然存在。为了解决这一问题,出现了控制反转(Inversion of Control, IoC)的设计思想。控制反转,实际上是“获得依赖对象的过程被反转”,传统的面向对象设计思想中,如果class A依赖class B类型的对象,通常的做法是在class A中,通过new操作符,创建一个class B的对象。这种做法就使得不同对象之间发生了耦合(图1), 如果class B的构造方法发生改变,所有使用new操作的相应代码均需要进行改变。而利用控制反转思想设计之后,使得获得依赖对象的过程由自身管理变为了由IOC容器主动注入,从而解除了对象之间的相互依赖(图2)。
.NET Core6.0环境下使用Autofac框架对webAPI进行依赖注入改造_第1张图片

.NET Core6.0环境下使用Autofac框架对webAPI进行依赖注入改造_第2张图片

2. IoC改造前的示例实现

例如,我们有一个WebAPI接口,该接口实现根据id查询文章的功能。接口层利用服务层的articleService对象,实现查询功能。如下代码所示:

        /// 
        /// 根据id查询文章
        /// 
        /// 
        /// 
        [HttpGet("{id}", Name ="Get")]
        public async Task<List<Article>> Get(int id)
        {
            IArticleService articleService = new ArticleService();
            return await articleService.GetListAsync(d => d.Id == id);
        }

上述代码实现,使得接口层依赖了服务层,如果创建ArticleService的方法发生变化,接口层也必须做相应更改。这就是对象依赖造成的问题的具体体现。

3. 使用AutoFac框架进行IoC改造

AutoFac是一个轻量级的开源框架,使用AutoFac框架提供的容器,可以快速完成控制反转的改造。具体做法如下:
1.使用Nuget在项目中添加Autofac.Extensions.DependencyInjection与Autofac.Extras.DynamicProxy依赖包(图3)。
.NET Core6.0环境下使用Autofac框架对webAPI进行依赖注入改造_第3张图片
2. 创建服务提供工厂
在Program.cs文件主函数入口处,创建服务提供工厂。

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); //创建服务提供工厂
  1. 注册后续依赖注入过程中需要的类型
    新建一个AutofacModuleRegister模块,继承自Autofac.Module,在Load方法中注册后续依赖注入过程中需要使用的的类型。
namespace SwiftCode.BBS.Extensions.ServiceExtensions
{
    public class AutofacModuleRegister : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<ArticleService>().As<IArticleService>();
        }
    }
}
  1. 配置实体依赖容器
    在程序启动入口处,配置实体依赖容器,将AutofacModuleRegister模块添加至实体依赖容器中。
            var builder = WebApplication.CreateBuilder(args);
            builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
            builder.Host.ConfigureContainer<ContainerBuilder>(builder => 
            {
                builder.RegisterModule<AutofacModuleRegister>();
            });

5.使用依赖注入的方式改造API接口
最后,使用依赖注入的方式改造API接口,在ArticleController实例化时,带参数的构造函数会去前面配置好的IoC容器中实例化articleService对象,并赋值给_articleService。至此,接口层不在负责服务层对象的创建,该对象变成了通过IoC容器注入。从而实现了解耦。

    /// 
    /// 文章接口
    /// 
    [Route("api/[controller]")]
    [ApiController]
    public class ArticleController : ControllerBase
    {
        private readonly IArticleService _articleService;

        /// 
        /// 利用构造函数注入articleService
        /// 
        /// 
        public ArticleController(IArticleService articleService)
        {
            _articleService = articleService;
        }

        /// 
        /// 根据id查询文章
        /// 
        /// 
        /// 
        [HttpGet("{id}", Name ="Get")]
        public async Task<List<Article>> Get(int id)
        {
            //IArticleService articleService = new ArticleService();
            return await _articleService.GetListAsync(d => d.Id == id);
        }
    }

4. 更进一步

我们通常使用分层设计的思想对软件系统进行架构设计。WEB后台应用程序通常被划分为接口层,服务层,数据仓储层等。往往接口层会依赖服务层,服务层又依赖数据仓储层。同学们可以尝试使用上述控制反转的设计思想,检视项目代码,使用控制反转的思想对更多的地方进行改造,消除对象之间的耦合性。

你可能感兴趣的:(编辑器)