• C# , .netWebApi 实现类似Java 的Ioc 自动装配@Autowired


    写C# 一直很羡慕Java的@Autowired 自动装配. 因为C# 必须手动在Ioc里注册,
    例如

    builder.Services.AddSingleton<IHostedService, StartupInitializationService>();
    
    • 1

    但是我们也可以用C# 的反射机制 , 用接口实现自动装配. 写接口, 扩展方法如下:

    namespace MyFanucApi.Service.Ioc
    {
        public interface IScoped
        {
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    namespace MyFanucApi.Service.Ioc
    {
        public interface ISingleton
        {
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    namespace MyFanucApi.Service.Ioc
    {
        public interface ITransient
        {
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    using System.Reflection;
    
    namespace MyFanucApi.Service.Ioc
    {
        public static class AutoRegister
        {
            public static IServiceCollection RegisterAllServices(this IServiceCollection services)
            {
                //获取当前程序集
                var entryAssembly = Assembly.GetEntryAssembly();
    
                //获取所有类型
                //!. null包容运算符,当你明确知道表达式的值不为null 使用!.(即null包容运算符)可以告知编译器这是预期行为,不应发出警告
                //例: entryAssembly!.GetReferencedAssemblies() 正常
                //entryAssembly.GetReferencedAssemblies() 编译器判断entryAssembly有可能为null,变量下方出现绿色波浪线警告
    
                var types = entryAssembly!.GetReferencedAssemblies()//获取当前程序集所引用的外部程序集
                    .Select(Assembly.Load)//装载
                    .Concat(new List<Assembly>() { entryAssembly })//与本程序集合并
                    .SelectMany(x => x.GetTypes())//获取所有类
                    .Distinct();//排重
    
                //三种生命周期分别注册
                Register<ITransient>(types, services.AddTransient, services.AddTransient);
                Register<IScoped>(types, services.AddScoped, services.AddScoped);
                Register<ISingleton>(types, services.AddSingleton, services.AddSingleton);
    
                return services;
            }
    
            /// 
            /// 根据服务标记的生命周期interface,不同生命周期注册到容器里面
            /// 
            /// 注册的生命周期
            /// 集合类型
            /// 委托:成对注册
            /// 委托:直接注册服务实现
            private static void Register<TLifetime>(IEnumerable<Type> types, Func<Type, Type, IServiceCollection> register, Func<Type, IServiceCollection> registerDirectly)
            {
                //找到所有标记了Tlifetime生命周期接口的实现类
                var tImplements = types.Where(x => x.IsClass && !x.IsAbstract && x.GetInterfaces().Any(tinterface => tinterface == typeof(TLifetime)));
    
                //遍历,挨个以其他所有接口为key,当前实现为value注册到容器中
                foreach (var t in tImplements)
                {
                    //获取除生命周期接口外的所有其他接口
                    var interfaces = t.GetInterfaces().Where(x => x != typeof(TLifetime));
                    if (interfaces.Any())
                    {
                        foreach (var i in interfaces)
                        {
                            register(i, t);
                        }
                    }
    
                    //有时需要直接注入实现类本身
                    registerDirectly(t);
                }
            }
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    在Ioc中注册:

    //自动注入
    builder.Services.RegisterAllServices();
    
    • 1
    • 2

    这样, 凡是实现接口IScoped , ISingleton 的类都在Ioc中自动注册了

  • 相关阅读:
    linux升级openssh9
    NATAPP使用详细教程(免费隧道内网映射)
    Docker的奇幻漂流
    Firefox Focus,一个 “专注“ 的浏览器
    国家高新技术企业多少分通过?申请条件是什么?
    MQ收到无序的消息时如何进行业务处理
    【ROS】机械人开发三--ROS工作空间与功能包
    LCR 027.回文链表
    685. 冗余连接 II--(每日一难phase--day13)
    Jmeter —— jmeter利用取样器中http发送请求
  • 原文地址:https://blog.csdn.net/helldoger/article/details/133849666