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


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

    之前用接口实现了自动注册IOC, 总是觉得美中不足, 毕竟没有真正实现用注解/特性实现自动注入, 这次我们来实现一个用特性注入Ioc的扩展方法.

    namespace MyCode.BLL.Service.Ioc
    {
        /// 
        /// 类型的生命周期枚举
        /// 
        public enum Lifetime
        {
            /// 
            /// 单例
            /// 
            Singleton,
            /// 
            /// 多例
            /// 
            Transient,
            Scoped
    
        }
    
        /// 
        /// 标注类型的生命周期、是否自动初始化
        /// 
        [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
        public class ExposedServiceAttribute : Attribute
        {
            public Lifetime Lifetime { get; set; }
    
            public bool AutoInitialize { get; set; }
    
            public Type[] Types { get; set; }
    
            public ExposedServiceAttribute(Lifetime lifetime = Lifetime.Transient, params Type[] types)
            {
                Lifetime = lifetime;
                Types = types;
            }
        }
    }
    
    
    • 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
    using Microsoft.Extensions.DependencyInjection;
    using MyCode.BLL.Service.Ioc;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    
    namespace MyCode.Utils.AttributeIoc
    {
        public static class DependencyExtension
        {
            /// 
            /// 获取class, 非抽象类, 特性有ExposedServiceAttribute 注解
            /// 
            /// 
            /// 
            //private static List GetTypes(Assembly assembly)
            //{
            //    var result = assembly
            //        .GetTypes()
            //        .Where(
            //            t =>
            //                t != null
            //                && t.IsClass
            //                && !t.IsAbstract
            //                && t.CustomAttributes.Any(
            //                    p => p.AttributeType == typeof(ExposedServiceAttribute)
            //                )
            //        )
            //        .ToList();
    
            //    return result;
            //}
    
            private static List<Type> MyGetTypes()
            {
                //获取当前程序集
                var entryAssembly = Assembly.GetEntryAssembly();
                var types = entryAssembly!
                    .GetReferencedAssemblies() //获取当前程序集所引用的外部程序集
                    .Select(Assembly.Load) //装载
                    .Concat(new List<Assembly>() { entryAssembly }) //与本程序集合并
                    .SelectMany(x => x.GetTypes()) //获取所有类
                    .Where(
                        t =>
                            t != null
                            && t.IsClass
                            && !t.IsAbstract
                            && t.CustomAttributes.Any(
                                p => p.AttributeType == typeof(ExposedServiceAttribute)
                            )
                    )
                    .Distinct() //排重
                    .ToList();
                ; 
    
                return types;
            }
    
            //public static void RegisterAssembly(this IServiceCollection services, Assembly assembly)
            //{
            //    var list = GetTypes(assembly);
            //    foreach (var type in list)
            //    {
            //        RegisterAssembly(services, type);
            //    }
            //}
    
            /// 
            /// 加this 表示 IServiceCollection 的扩展方法
            /// 
            /// 
            public static void RegisterAssembly(this IServiceCollection services)
            {
                var list = MyGetTypes();
                foreach (var type in list)
                {
                    RegisterAssembly(services, type);
                }
            }
    
    
    
            public static void RegisterAssembly(IServiceCollection services, Type type)
            {
                var list = GetExposedServices(type).ToList();
    
                foreach (var item in list)
                {
                    switch (item.Lifetime)
                    {
                        case Lifetime.Singleton:
                            services.AddSingleton(type);
                            break;
                        case Lifetime.Transient:
                            services.AddTransient(type);
                            break;
                        case Lifetime.Scoped:
                            services.AddScoped(type);
                            break;
                        default:
                            break;
                    }
    
                    foreach (var IType in item.Types)
                    {
                        switch (item.Lifetime)
                        {
                            case Lifetime.Singleton:
                                services.AddSingleton(IType, type);
                                break;
                            case Lifetime.Transient:
                                services.AddTransient(IType, type);
                                break;
                            case Lifetime.Scoped:
                                services.AddScoped(IType, type);
                                break;
                            default:
                                break;
                        }
                    }
                }
            }
    
    
    
    • 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
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125

    在Ioc注册:

    services.RegisterAssembly();
    
    • 1

    在View中使用:

    using MyCode.BLL.Service.Ioc;
    using System.Windows;
    
    namespace MyCode.Views
    {
        /// 
        /// MainView.xaml 的交互逻辑
        /// 
    
        [ExposedService(Lifetime.Singleton)]
        public partial class MainView : Window
        {
            public MainView()
            {
                InitializeComponent();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    成功结果:

    在这里插入图片描述

  • 相关阅读:
    Java之线程的详细解析二
    2023CCPC网络赛(A E)
    SAP ABAP openSQL数据库操作(三)
    【无标题】
    基于I/Q数据的5G控制信道盲检
    Springboot毕设项目会议管理系统95p57(java+VUE+Mybatis+Maven+Mysql)
    10 年国内算法大神经验总结的数据结构与算法详解终于学完
    过滤器 监听器
    单例模式 rust和java的实现
    Bit.Store:熊市漫漫,稳定Staking产品或成主旋律
  • 原文地址:https://blog.csdn.net/helldoger/article/details/134343957