.Net5 WebApi中使用Autofac作为IOC容器(已在生产环境中使用)

2023-10-30

安装Autofac

我是使用Nuget安装两个Autofac:

  1. install-package Autofac
  2. install-package Autofac.Extensions.DependencyInjection

创建一个独立模块来实现动态依赖注入(也可以常规使用,我这里只讲解独立模块的依赖注入)

创建一个类,继承Autofac的模块类Module,然后重写父类的Load方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autofac;
using Levox.Framework.Core.Extensions;
using Levox.Framework.Core.Logger;
using Levox.Framework.Core.Models.Inject;
using Microsoft.AspNetCore.Mvc;
using Module = Autofac.Module;

namespace Levox.Framework.Core.ServiceInject
{
    /// <summary>
    /// ERP服务依赖注入   LastUpdateDate:2021-03-30 14:04:22.606  Author:Lingbug
    /// </summary>
    public class ErpServiceInjectModule : Module
    {
        /// <summary>
        /// 自定义注入   LastUpdateDate:2021-03-30 15:13:34.492  Author:Lingbug
        /// </summary>
        /// <param name="builder"></param>
        protected override void Load(ContainerBuilder builder)
        {
            //读取到所有需要依赖注入的程序集
            var assemblys = ServiceInjectUtil.GetLevoxAssemblys().ToArray();

            //注入服务
            LoadServices(builder, assemblys);
            //注入控制器
            LoadControllers(builder, assemblys);
        }

        /// <summary>
        /// 注入服务   LastUpdateDate:2021-03-30 14:44:15.803  Author:Lingbug
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="assemblys"></param>
        private void LoadServices(ContainerBuilder builder, Assembly[] assemblys)
        {
            //标识类
            var baseType = typeof(IErpApplicationService);
            //读取到需要注入的服务类
            var appServiceTypes = assemblys.SelectMany(a => a.GetTypes()).Where(r => !r.IsInterface && baseType.IsAssignableFrom(r)).ToList();
            //注入记录
            var records = new List<Tuple<string, string>>();
            foreach (var type in appServiceTypes)
            {
                //读取服务实现的接口
                var iServiceTypes = type.GetInterfaces().ToArray();
                //注入类型
                string registerTypeStr = null;
                if (iServiceTypes.Contains(typeof(IErpTransientApplicationService)))
                {
                    //瞬时注入,且允许循环依赖
                    builder.RegisterType(type).AsImplementedInterfaces().InstancePerDependency().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
                    //赋值注入类型
                    registerTypeStr = "Transient";
                }
                else if (iServiceTypes.Contains(typeof(IErpScopedApplicationService)))
                {
                    //单次请求注入,且允许循环依赖
                    builder.RegisterType(type).AsImplementedInterfaces().InstancePerLifetimeScope().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
                    //赋值注入类型
                    registerTypeStr = "Scope";
                }
                else
                {
                    //单例注入,且允许循环依赖
                    builder.RegisterType(type).AsImplementedInterfaces().SingleInstance().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
                    //赋值注入类型
                    registerTypeStr = "Singleton";
                }
                records.Add(new Tuple<string, string>(type.FullName, registerTypeStr));
            }
            //记录日志
            LoggerTestUtil.SimpleLog($"注入服务接口【count = {records.Count}】:{records.SerializeToJson()}");
        }

        /// <summary>
        /// 注入控制器   LastUpdateDate:2021-03-30 14:48:20.642  Author:Lingbug
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="assemblys"></param>
        private void LoadControllers(ContainerBuilder builder, Assembly[] assemblys)
        {
            //控制器类
            var baseControllerType = typeof(ControllerBase);
            //注入控制器
            builder.RegisterAssemblyTypes(assemblys).Where(r => baseControllerType.IsAssignableFrom(r)).PropertiesAutowired();
        }
    }
}

修改Program类,使用Autofac容器

.UseServiceProviderFactory(new AutofacServiceProviderFactory())

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Autofac.Extensions.DependencyInjection;
using Levox.Framework.WebApi.Extensions;
using Levox.Framework.Model.Input;

namespace Levox.NewERP.WebApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                //使用Autofac容器
                .UseServiceProviderFactory(new AutofacServiceProviderFactory())
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureErpServices(services =>
                    {
                        //一行代码将框架注入到容器
                        services.AddErpInject(new AddErpInjectOption());
                    });
                    webBuilder.UseStartup<Startup>();
                });
    }
}

在Startup类中添加Autofac启动方法,在该方法中使用刚在自定义模块类,Autofac会自动调用

public void ConfigureContainer(ContainerBuilder builder) => builder.RegisterModule<ErpServiceInjectModule>();

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Levox.Framework.Model.Input;
using Levox.Framework.WebApi.Extensions;
using Autofac;
using Levox.Framework.Core.Logger;
using Levox.Framework.Core.ServiceInject;

namespace Levox.NewERP.WebApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            //一行代码启动日志(注意配置文件路径必须为Config/log.config,且属性改为始终复制)
            LoggerInit.Init();
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {

        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            //一行代码启动框架
            app.UseErpConfiguration(env, new UseErpConfigurationOption());
        }

        /// <summary>
        /// 定义此方法,框架自动调用注入所有系统服务   LastUpdateDate:2021-04-01 18:30:41.633  Author:Lingbug
        /// </summary>
        /// <param name="builder"></param>
        public void ConfigureContainer(ContainerBuilder builder) => builder.RegisterModule<ErpServiceInjectModule>();
    }
}

开发Autofac工具类,存储容器,在某些场景可以手动解析服务

开发Autofac工具类

using Autofac;
using Microsoft.AspNetCore.Http;

namespace Levox.Framework.Core.ServiceInject
{
    /// <summary>
    /// Autofac工具类   LastUpdateDate:2021-03-30 15:52:26.527  Author:Lingbug
    /// </summary>
    public static class ServiceInjectUtil
    {
        /// <summary>
        /// IOC容器   LastUpdateDate:2021-03-30 14:53:31.530  Author:Lingbug
        /// </summary>
        public static ILifetimeScope Container { get; set; }

        /// <summary>
        /// 解析服务   LastUpdateDate:2021-03-30 14:53:11.290  Author:Lingbug
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetService<T>() where T : class => Container.Resolve<T>();

        /// <summary>
        /// 获取服务(此次请求生命周期内)   LastUpdateDate:2021-03-30 14:54:02.594  Author:Lingbug
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetScopeService<T>() where T : class
        {
            //解析请求上下文
            var httpContextAccessor = GetService<IHttpContextAccessor>();
            //解析服务
            var service = httpContextAccessor.HttpContext.RequestServices.GetService(typeof(T));
            //返回
            return (T)service;
        }
    }
}

在Startup的Configure方法中拿到Autofac容器,并存储起来供工具类使用

ServiceInjectUtil.Container = app.ApplicationServices.GetAutofacRoot();//获取到容器并存储

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Levox.Framework.Model.Input;
using Levox.Framework.WebApi.Extensions;
using Autofac;
using Levox.Framework.Core.Logger;
using Levox.Framework.Core.ServiceInject;

namespace Levox.NewERP.WebApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            //一行代码启动日志(注意配置文件路径必须为Config/log.config,且属性改为始终复制)
            LoggerInit.Init();
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {

        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            //获取到容器并存储
            ServiceInjectUtil.Container = app.ApplicationServices.GetAutofacRoot();
            //一行代码启动框架
            app.UseErpConfiguration(env, new UseErpConfigurationOption());
        }

        /// <summary>
        /// 定义此方法,框架自动调用注入所有系统服务   LastUpdateDate:2021-04-01 18:30:41.633  Author:Lingbug
        /// </summary>
        /// <param name="builder"></param>
        public void ConfigureContainer(ContainerBuilder builder) => builder.RegisterModule<ErpServiceInjectModule>();
    }
}

Autofac核心Api总结

序号 Api 说明
1 builder.RegisterType(type).AsImplementedInterfaces() 将type注入到它的所有实现类中
2 InstancePerDependency() 瞬时注入
4 InstancePerLifetimeScope() 单次请求周期内注入
5 SingleInstance() 单例注入
6 PropertiesAutowired() 支持属性注入
7 PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies) 支持属性注入且允许循环依赖
8 builder.RegisterModule<ErpServiceInjectModule>() 注入模块
9 public void ConfigureContainer(ContainerBuilder builder) => builder.RegisterModule<ErpServiceInjectModule>(); Startup定义方法模块注入,供Autofac自动调用
10 ServiceInjectUtil.Container = app.ApplicationServices.GetAutofacRoot(); Startup中获取Autofac容器,并存储
11 .UseServiceProviderFactory(new AutofacServiceProviderFactory()) Program使用Autofac
12 builder.RegisterAssemblyTypes(assemblys).Where(r => typeof(ControllerBase).IsAssignableFrom(r)).PropertiesAutowired(); 注入控制器
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.Net5 WebApi中使用Autofac作为IOC容器(已在生产环境中使用) 的相关文章

随机推荐

  • 【Hello mysql】 mysql的内外连接 (重点)

    Mysql专栏 Mysql 本篇博客简介 介绍mysql的内外连接 mysql的内外连接 重点 内连接 显示SMITH的名字和部门名称 外连接 左外连接 右外连接 总结 表的内外连接是mysql中比较常用的内容 也是我们学习mysql的重点
  • Python str函数

    描述 str函数是Python的内置函数 它将参数转换成字符串类型 即人适合阅读的形式 语法 str object 名称 说明 备注 object 待被转换成字符串的参数 可省略的参数 返回值 返回object的字符串形式 使用示例 1 无
  • vue.js 输入框输入值自动过滤特殊字符替换中问标点

  • 搜寻吉祥数,在给定的范围内,例如1~99999,找出吉祥数字,满足的条件为:全部数字必须由6或者8构成,如66666,66668,668,…

    题目 在给定的范围内 例如1 99999 找出吉祥数字 满足的条件为 全部数字必须由6或者8构成 如66666 66668 668 1 一开始想的很杂 考虑了效率 把要查找的数转化成String再转化成char数组 逐个跟 6 8 比较 但
  • 随机变量列的四种收敛性

    极限定理是研究随机变量列的收敛性 在学习中遇到了随机变量列的四种收敛性 几乎处处收敛 a e 收敛 以概率收敛 P 收敛 依分布收敛 d 收敛 k阶矩收敛 下面是对它们的吐血整理 考虑一个随机变量列 n c为一个常数 由于随机性不能直接刻画
  • 基于stm32f103c8t6的定时器详解(持续更新)

    一 stm32f103系列定时器介绍 先声明 stm32f103c8t6中没有基本定时器 只有TIM1 TIM4 分别是高级定时器和通用定时器 对照下图请自行阅读stm32f103x的datasheet 1 定时器功能 定时 输出比较 输入
  • Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘commit‘)

    问题 使用vuex的时候 调用this store commit 方法名 参数 的时候 报了这个错 搜索到的解决方法都是在说什么store没在main js里vue实例中挂载 而我 已经挂得好好的了 给我气坏了 解决策略 我问题在于 没有把
  • Vue开发环境搭建和vue-cli脚手架

    vue本质是一个js脚本 提供了一个前端框架 在开发时 可以直接引入这个js脚本 也可以使用脚手架工具 在本地搭建一个项目 Vue js安装 方法一 在 Vue js 的官网上直接下载 vue min js 并用
  • 质量铁三角

    文章目录 质量铁三角 1 流程 2 技术 3 组织 质量铁三角 1 流程 从计划到策略的实现 流程就是按照这种思维方式指导软件开发的 并且流程来源于成功的经验 可以指导项目少走弯路 从而提高软件质量 不仅如此 流程还对项目的成本和进度控制有
  • 树的Hash方法?

    写这篇博文的主要还是因为自己菜得抠脚 弱校联盟的十一专场的第三天是JAG Practice Contest for ACM ICPC Asia Regional 2016 其中的E题大意是给一颗有根树 问有多少对子树每个深度的节点数都相同
  • 【C语言】顺序表的创建

    一 代码实现部分 1 顺序表是线性表的基础部分 至于顺序表 在本人看来无异于数组 至于线性表的概念 在此不再赘述 接下来尝试利用C语言对线性表中的顺序表进行代码实现 此程序中规定用户输入的数据类型为int类型 typedef struct
  • one大白陪你聊聊2021年总结

    我的2021 工作方面 感情方面 生理方面 心理方面 生活方面 重要的事情 工作方面 21年换了一份工作 薪资有了一点提升 技术方面提升有些缓慢 直到21年底才想起 察觉到自己对于技术方面今天没咋进步 开始每周的技术提升计划 一周学习8小时
  • 数据分析与挖掘(十八)------挖掘建模之时序模式

    一 引言 就餐饮企业而言 经常会碰到如下问题 由于餐饮行业是生产和销售同时进行 因此销售预测对于餐饮企业十分必要 如何基于菜品历史销售数据 做好餐饮销售预测 以便减少菜品脱销现象和避免因备料不足而造成的生产延误 从而减少菜品生产等待时间 提
  • 怎么彻底删除电脑上的软件_如何用一行代码彻底删除电脑捆绑的流氓软件!

    你是否有过这样的烦恼 只想下载软件A 一个不小心给我捆绑了B C D E F等等我不需要的流氓全家桶软件 那是相当的痛苦啊 删除又删除不干净 这可如何是好 今天我们一起来看如何一行代码就可以将这些流氓捆绑软件全部找出并彻底清理
  • 最小二乘法入门(Matlab直线和曲线拟合)

    参考博客 https blog csdn net wokaowokaowokao12345 article details 72850143 多的就不多说了 持续脱发中 最小二乘法历史起源之类的 https baike baidu com
  • 前端三剑客_CSS

    前端三剑客 CSS 1 CSS简介
  • span标签之间有空格怎么办

    span标签之间有空格 span标签之间有很大空格 代码如下
  • 脚手架创建的 ant-design-pro 6 mock接口404

    大家好 我是鱼尾 今天分享一个前端小知识 我在使用ant design pro脚手架创建项目碰到的一个问题 复现过程 使用 npm 初始化 创建项目 npm i ant design pro cli g pro create myproje
  • 网络安全公开数据集

    DARPA入侵检测数据集 DARPA 1998数据集 收集了9周的 TCPDUMP网络连接和系统审计数据 7周的训练数据 2周的测试数据 包含了Probe DoS R2L U2R四大类攻击 DARPA 1999数据集 DARPA 1999覆
  • .Net5 WebApi中使用Autofac作为IOC容器(已在生产环境中使用)

    本文讲解在 Net5 WebApi中使用Autofac作为IOC容器 已在生产环境中使用 安装Autofac 创建一个独立模块来实现动态依赖注入 也可以常规使用 我这里只讲解独立模块的依赖注入 修改Program类 使用Autofac容器