• 第四十一节:再探依赖注入(coreMvc/应用启动/控制台)和多项目框架集成(原生反射、AutoFac集成新写法)


    一. 再探依赖注入

    其它详细用法参考之前的博客:https://www.cnblogs.com/yaopengfei/p/10754397.html  
                                                   https://www.cnblogs.com/yaopengfei/p/12664400.html
    官网:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-6.0

    1. coreMvc中注入

        直接在Program中注入即可, 可以以接口的形式注入,也可以直接注入类

    //1. 普通注入
    builder.Services.AddScoped<IUserInfo, UserInfo>();
    builder.Services.AddScoped<RoleInfo>();

        使用的时候在控制器中通过构造函数注入即可,代码略。

    2. 在应用启动中解析

     (即在program中要使用,这里是解析使用,注册使用的还是1中的注册)

     (1). 通过 var serviceScope = app.Services.CreateScope()

     (2). 通过GetRequiredService方法进行对象的解析

    var app = builder.Build();
    
    //2.在应用启动中解析使用(使用的还是1中的普通注入)
    using (var serviceScope = app.Services.CreateScope())
    {
        var services = serviceScope.ServiceProvider;
        var userInfo = services.GetRequiredService<IUserInfo>();
        var roleInfo = services.GetRequiredService<RoleInfo>();
        Console.WriteLine("------------------测试在应用启动中解析使用------------------------------");
        Console.WriteLine(userInfo.GetInfo());
        Console.WriteLine(roleInfo.GetInfo());
    }

    3.直接在控制台中使用

     直接注册+解析

     需要依赖【 Microsoft.Extensions.DependencyInjection】程序集,详见下面代码

                 //3. 测试控制台中使用
                {
                    var serviceCollection = new ServiceCollection();
                    serviceCollection.AddSingleton<IUserInfo, UserInfo>();
                    var serviceProvider = serviceCollection.BuildServiceProvider();
                    IUserInfo userService = serviceProvider.GetRequiredService<IUserInfo>();
    
                    //下面是使用
                    var result = userService.GetInfo();
                }

    二. 多项目框架集成

    1. 需求

      有多个项目, Ypf.Service、Ypf.IService、03-CoreMvcDI三个项目, 其中CoreMvcDI添加对Ypf.Service的引用,然后把Ypf.Service项目的输出路径改为 【..\03-CoreMvcDI\bin\】

      想把Ypf.Service中所有实现ISupport接口的类注册个他的实现接口

      [FromServices] IInfo2 _info2 是注册失败的,因为没有实现ISupport接口 (需要加上以后再测试一下哦)

    特别注意:这里的输出路径改为 Ypf.Service项目的输出路径改为 【..\03-CoreMvcDI\bin\】,利用合并文件夹的原则实现!!!  因为Ypf.Service项目也会生成一个Debuger文件夹

    2. 原生反射写法

    (和之前Core5.0中的写法基本一致)

    (1). 拼接dll的路径,通过反射进行加载

    (2). 获取该dll中的符合条件的类(A.去掉抽象类 B.该类要实现ISupport接口)

    (3). 遍历类

       A. 拿到该类的所有接口(去掉ISupport接口)

       B. 遍历接口,把该类注册给所有实现的接口

    代码分享:

    {
    
        var dirName = "03-Ypf.Service.dll";
        Assembly asmService = Assembly.LoadFile(AppContext.BaseDirectory + dirName);
        //抽象类不进行注入,没有实现ISupport接口的类不进行注入
        var classList = asmService.GetTypes().Where(t => !t.GetTypeInfo().IsAbstract && typeof(ISupport).IsAssignableFrom(t)).ToList();
        foreach (Type serviceType in classList)
        {
            //把一个类注册给它实现的全部接口(除了ISupport接口外)
            var interfaceTypes = serviceType.GetInterfaces().Where(t => t.Name != "ISupport").ToList();
            foreach (var interfaceType in interfaceTypes)
            {
                builder.Services.AddScoped(interfaceType, serviceType);
            }
        }
    
    }

    3. AutoFac集成新写法

       和之前Core5.0的写法有区别,详见Program中的代码

    封装MyAutoFacModule类
     public class MyAutoFacModule : Module
        {
            protected override void Load(ContainerBuilder builder)
            {
                {
                    //这里就是AutoFac的注入方式,下面采用常规的方式
                    //详见:https://www.cnblogs.com/yaopengfei/p/9479268.html
                    //官网:https://autofac.org/
    
                    //特别注意:其中很大的一个变化在于,Autofac 原来的一个生命周期InstancePerRequest,将不再有效。正如我们前面所说的,整个request的生命周期被ASP.NET Core管理了,
                    //所以Autofac的这个将不再有效。我们可以使用 InstancePerLifetimeScope ,同样是有用的,对应了我们ASP.NET Core DI 里面的Scoped。
    
                   //在普通类中配置文件的读取麻烦,后面封装(注:appsettings.json要改为始终复制)
                    var Configuration = new ConfigurationBuilder().AddJsonFile(AppContext.BaseDirectory + "appsettings.json").Build();
                    var dirName = Configuration["IocDll"];
                    Assembly asmService = Assembly.LoadFile(AppContext.BaseDirectory + dirName);
    
                    builder.RegisterAssemblyTypes(asmService)
                           .Where(t => !t.IsAbstract && typeof(ISupport).IsAssignableFrom(t))  //只有实现了ISupport接口的类才进行注册
                           .AsImplementedInterfaces()    //把一个类注册给它实现的全部接口
                           .InstancePerLifetimeScope()   //作用域单例(比如Task.Run就是另外一个作用域),而非请求内单例(请求内单例用:InstancePerRequest)
                           .PropertiesAutowired();       //在core里表示在注入类中实现构造函数注入
                }
            }
        }
    program中的代码(和5.0的写法有区别了) 
        builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
        // Register services directly with Autofac here. Don't call builder.Populate(), that happens in AutofacServiceProviderFactory.
        builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.RegisterModule(new MyAutoFacModule()));
     
     

    三. 老杨的开源框架

       https://github.com/yangzhongke/NETBookMaterials/tree/main/%E6%9C%80%E5%90%8E%E5%A4%A7%E9%A1%B9%E7%9B%AE%E4%BB%A3%E7%A0%81/YouZack-VNext/Zack.Commons


       主要分析RunModuleInitializers方法和ReflectionHelper.cs

    !

    • 作       者 : Yaopengfei(姚鹏飞)
    • 博客地址 : http://www.cnblogs.com/yaopengfei/
    • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
    • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
     
  • 相关阅读:
    相关正则的一些知识
    数组中的方法
    封装ajax
    swiper结合ajax的轮播图
    事件
    原型、原型链
    HTML 常用标签
    HTML基础了解
    JSON 与 XML基本了解
    JavaScript(js)
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/16277136.html
Copyright © 2020-2023  润新知