AssemblyManager 程序集管理器

27 篇文章 0 订阅

AssemblyManager 程序集管理器

程序执行中使用反射对框架的搭建有着强大的影响,如何管理程序集方便使用反射获取类型操作对象是本文章的重点

1.AssemblyInfo

对于一个程序集这里使用一个AssemblyInfo对象进行管理

  • Assembly :对应的程序集
  • AssemblyTypeList :该程序集中所有对象的类型(包括接口、抽象类等)
  • AssemblyTypeGroupList :一个key对应多个值的字典存储对应的接口对应的派生类(Key:某个接口类型,Value:继承这个接口的类对象类型)
        public Assembly Assembly { get; private set; }
        public readonly List<Type> AssemblyTypeList = new List<Type>();
        public readonly OneToManyList<Type, Type> AssemblyTypeGroupList = new OneToManyList<Type, Type>();

完整的AssemblyInfo代码

    public sealed class AssemblyInfo
    {
        public Assembly Assembly { get; private set; }
        public readonly List<Type> AssemblyTypeList = new List<Type>();
        public readonly OneToManyList<Type, Type> AssemblyTypeGroupList = new OneToManyList<Type, Type>();

        public void Load(Assembly assembly)
        {
            Assembly = assembly;
            Type[] assemblyTypes = Assembly.GetTypes();
            foreach (Type type in assemblyTypes) 
            {
                if (type.IsAbstract || type.IsInterface)
                    continue;
                Type[] interfaces = type.GetInterfaces();
                foreach (Type interfaceType in interfaces)
                {
                    AssemblyTypeGroupList.Add(interfaceType, type);
                }
            }
            AssemblyTypeList.AddRange(assemblyTypes);
        }

        public void UnLoad()
        {
            AssemblyTypeList.Clear();
            AssemblyTypeGroupList.Clear();
        }
    }

2.AssemblyManager

三个事件(加载某个程序集事件、卸载某个程序集事件、重新加载某个程序集事件)
字典对应的是程序集名称(使用int)对应的程序集信息AssemblyInfo

        public static event Action<int> OnLoadAssemblyEvent;
        public static event Action<int> OnUnLoadAssemblyEvent;
        public static event Action<int> OnReLoadAssemblyEvent;
        private static Dictionary<int, AssemblyInfo> AssemblyList = new Dictionary<int, AssemblyInfo>();

主要方法加载某个程序集

        public static void LoadAssembly(int assemblyName, Assembly assembly)
        {
            bool isReload = false;
            if (!AssemblyList.TryGetValue(assemblyName, out AssemblyInfo assemblyInfo))
            {
                assemblyInfo = new AssemblyInfo();
                AssemblyList.Add(assemblyName, assemblyInfo);
            }
            else
            {
                isReload = true;
                assemblyInfo.UnLoad();
                if (OnUnLoadAssemblyEvent != null)
                {
                    OnUnLoadAssemblyEvent(assemblyName);
                }
            }

            assemblyInfo.Load(assembly);

            if (OnLoadAssemblyEvent != null)
            {
                OnLoadAssemblyEvent(assemblyName);
            }

            if (isReload && OnReLoadAssemblyEvent != null)
            {
                OnReLoadAssemblyEvent(assemblyName);
            }
        }

其余遍历程序集方法,根据不同的方式去遍历程序集
在这里插入图片描述
完整AssemblyManager代码

    public static class AssemblyManager
    {
        public static event Action<int> OnLoadAssemblyEvent;
        public static event Action<int> OnUnLoadAssemblyEvent;
        public static event Action<int> OnReLoadAssemblyEvent;
        private static Dictionary<int, AssemblyInfo> AssemblyList = new Dictionary<int, AssemblyInfo>();
        public static void LoadAssembly(int assemblyName, Assembly assembly)
        {
            bool isReload = false;
            if (!AssemblyList.TryGetValue(assemblyName, out AssemblyInfo assemblyInfo))
            {
                assemblyInfo = new AssemblyInfo();
                AssemblyList.Add(assemblyName, assemblyInfo);
            }
            else
            {
                isReload = true;
                assemblyInfo.UnLoad();
                if (OnUnLoadAssemblyEvent != null)
                {
                    OnUnLoadAssemblyEvent(assemblyName);
                }
            }

            assemblyInfo.Load(assembly);

            if (OnLoadAssemblyEvent != null)
            {
                OnLoadAssemblyEvent(assemblyName);
            }

            if (isReload && OnReLoadAssemblyEvent != null)
            {
                OnReLoadAssemblyEvent(assemblyName);
            }
        }
        public static IEnumerable<int> ForeachAssemblyName()
        {
            foreach (int assemblyName in AssemblyList.Keys)
            {
                yield return assemblyName;
            }
        }
        public static IEnumerable<Type> Foreach()
        {
            foreach (AssemblyInfo assemblyInfo in AssemblyList.Values)
            {
                foreach (Type type in assemblyInfo.AssemblyTypeList)
                {
                    yield return type;
                }
            }
        }
        public static IEnumerable<Type> Foreach(int assemblyName)
        {
            if (!AssemblyList.TryGetValue(assemblyName, out AssemblyInfo assemblyInfo))
                yield break;
            foreach (Type type in assemblyInfo.AssemblyTypeList) { yield return type; }
        }
        public static IEnumerable<Type> Foreach(Type findType)
        {
            foreach (AssemblyInfo assemblyInfo in AssemblyList.Values)
            {
                if(!assemblyInfo.AssemblyTypeGroupList.TryGetValue(findType,out List<Type> assemblyLoad))
                    yield break;

                foreach (Type type in assemblyLoad)
                {
                    yield return type;
                }
            }
        }
        public static IEnumerable<Type> Foreach(int assemblyName, Type findType)
        {
            if (!AssemblyList.TryGetValue(assemblyName, out AssemblyInfo assemblyInfo))
                yield break;

            if(!assemblyInfo.AssemblyTypeGroupList.TryGetValue(findType,out List<Type> classList))
                yield break;

            foreach(Type type in classList)
                yield return type;
        }
        public static Assembly GetAssembly(int assemblyName)
        {
            return !AssemblyList.TryGetValue(assemblyName, out AssemblyInfo assemblyInfo) ? null : assemblyInfo.Assembly;
        }
        public static void Dispose()
        {
            foreach (AssemblyInfo assemblyInfo in AssemblyList.Values)
            {
                assemblyInfo.UnLoad();
            }

            AssemblyList.Clear();

            if(OnLoadAssemblyEvent != null)
            {
                foreach (var @delegate in OnLoadAssemblyEvent.GetInvocationList())
                {
                    OnLoadAssemblyEvent -= @delegate as Action<int>;
                }
            }

            if (OnUnLoadAssemblyEvent != null)
            {
                foreach (var @delegate in OnUnLoadAssemblyEvent.GetInvocationList())
                {
                    OnUnLoadAssemblyEvent -= @delegate as Action<int>;
                }
            }

            if (OnReLoadAssemblyEvent != null)
            {
                foreach (var @delegate in OnReLoadAssemblyEvent.GetInvocationList())
                {
                    OnReLoadAssemblyEvent -= @delegate as Action<int>;
                }
            }

            OnLoadAssemblyEvent = null;
            OnUnLoadAssemblyEvent = null;
            OnReLoadAssemblyEvent = null;
        }
    }

3.测试

准备测试的类和接口

    public interface ITest1
    {

    }

    public interface ITest2
    {

    }

    public class TestClass0 
    {

    }

    public class TestClass1 : ITest1
    {

    }

    public class TestClass2 : ITest2
    {

    }

    public class TestClass3 : ITest1, ITest2
    {

    }

进行测试代码

public class Program
    {
        static void Main(string[] args)
        {
            AssemblyManager.OnLoadAssemblyEvent += (assemblyName) =>
            {
                Console.WriteLine($"加载程序集 : {assemblyName}");
            };
            AssemblyManager.OnReLoadAssemblyEvent += (assemblyName) =>
            {
                Console.WriteLine($"重新加载程序集 : {assemblyName}");
            };
            AssemblyManager.OnUnLoadAssemblyEvent += (assemblyName) =>
            {
                Console.WriteLine($"卸载程序集 : {assemblyName}");
            };
            AssemblyManager.LoadAssembly(1, typeof(Program).Assembly);
            foreach (Type type in AssemblyManager.Foreach())
            {
                Console.WriteLine(type.FullName);
            }
            Console.WriteLine("=================================");
            foreach (Type type in AssemblyManager.Foreach(1,typeof(ITest1)))
            {
                Console.WriteLine(type.FullName);
            }
            Console.WriteLine("=================================");
            foreach (Type type in AssemblyManager.Foreach(1, typeof(ITest2)))
            {
                Console.WriteLine(type.FullName);
            }
            Console.ReadKey();
        }
    }

执行结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值