栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

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

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

本文讲解在.Net5 WebApi中使用Autofac作为IOC容器(已在生产环境中使用)
  • 安装Autofac
  • 创建一个独立模块来实现动态依赖注入(也可以常规使用,我这里只讲解独立模块的依赖注入)
  • 修改Program类,使用Autofac容器
  • 在Startup类中添加Autofac启动方法,在该方法中使用刚在自定义模块类,Autofac会自动调用
  • 开发Autofac工具类,存储容器,在某些场景可以手动解析服务
    • 开发Autofac工具类
    • 在Startup的Configure方法中拿到Autofac容器,并存储起来供工具类使用
  • Autofac核心Api总结

安装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
{
    /// 
    /// ERP服务依赖注入   LastUpdateDate:2021-03-30 14:04:22.606  Author:Lingbug
    /// 
    public class ErpServiceInjectModule : Module
    {
        /// 
        /// 自定义注入   LastUpdateDate:2021-03-30 15:13:34.492  Author:Lingbug
        /// 
        /// 
        protected override void Load(ContainerBuilder builder)
        {
            //读取到所有需要依赖注入的程序集
            var assemblys = ServiceInjectUtil.GetLevoxAssemblys().ToArray();

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

        /// 
        /// 注入服务   LastUpdateDate:2021-03-30 14:44:15.803  Author:Lingbug
        /// 
        /// 
        /// 
        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>();
            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(type.FullName, registerTypeStr));
            }
            //记录日志
            LoggerTestUtil.SimpleLog($"注入服务接口【count = {records.Count}】:{records.SerializeToJson()}");
        }

        /// 
        /// 注入控制器   LastUpdateDate:2021-03-30 14:48:20.642  Author:Lingbug
        /// 
        /// 
        /// 
        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类中添加Autofac启动方法,在该方法中使用刚在自定义模块类,Autofac会自动调用

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

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());
        }

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

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

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

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

        /// 
        /// 获取服务(此次请求生命周期内)   LastUpdateDate:2021-03-30 14:54:02.594  Author:Lingbug
        /// 
        /// 
        /// 
        public static T GetScopeService() where T : class
        {
            //解析请求上下文
            var httpContextAccessor = GetService();
            //解析服务
            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());
        }

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

Autofac核心Api总结
序号Api说明
1builder.RegisterType(type).AsImplementedInterfaces()将type注入到它的所有实现类中
2InstancePerDependency()瞬时注入
4InstancePerLifetimeScope()单次请求周期内注入
5SingleInstance()单例注入
6PropertiesAutowired()支持属性注入
7PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies)支持属性注入且允许循环依赖
8builder.RegisterModule()注入模块
9public void ConfigureContainer(ContainerBuilder builder) => builder.RegisterModule();Startup定义方法模块注入,供Autofac自动调用
10ServiceInjectUtil.Container = app.ApplicationServices.GetAutofacRoot();Startup中获取Autofac容器,并存储
11.UseServiceProviderFactory(new AutofacServiceProviderFactory())Program使用Autofac
12builder.RegisterAssemblyTypes(assemblys).Where(r => typeof(ControllerBase).IsAssignableFrom(r)).PropertiesAutowired();注入控制器
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/911098.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号