zoukankan      html  css  js  c++  java
  • 【dotnet】程序集注入

        /// <summary>
        /// IServiceCollection扩展
        /// </summary>
        public static class ServiceExtension
        {
            /// <summary>
            /// 用DI批量注入接口程序集中对应的实现类。
            /// <para>
            /// 需要注意的是,这里有如下约定:
            /// IUserService --> UserService, IUserRepository --> UserRepository.
            /// </para>
            /// </summary>
            /// <param name="service"></param>
            /// <param name="interfaceAssemblyName">接口程序集的名称(不包含文件扩展名)</param>
            /// <returns></returns>
            public static IServiceCollection RegisterAssembly(this IServiceCollection service, string interfaceAssemblyName)
            {
                if (service == null)
                    throw new ArgumentNullException(nameof(service));
                if (string.IsNullOrEmpty(interfaceAssemblyName))
                    throw new ArgumentNullException(nameof(interfaceAssemblyName));
    
                var assembly = RuntimeService.GetAssembly(interfaceAssemblyName);
                if (assembly == null)
                {
                    throw new DllNotFoundException($"the dll "{interfaceAssemblyName}" not be found");
                }
    
                //过滤掉非接口及泛型接口
                var types = assembly.GetTypes().Where(t => t.GetTypeInfo().IsInterface && !t.GetTypeInfo().IsGenericType);
    
                foreach (var type in types)
                {
                    var implementTypeName = type.Name.Substring(1);
                    var implementType = RuntimeService.GetImplementType(implementTypeName, type);
                    if (implementType != null)
                        service.AddSingleton(type, implementType);
                }
                return service;
            }
    
            /// <summary>
            /// 用DI批量注入接口程序集中对应的实现类。
            /// </summary>
            /// <param name="service"></param>
            /// <param name="interfaceAssemblyName">接口程序集的名称(不包含文件扩展名)</param>
            /// <param name="implementAssemblyName">实现程序集的名称(不包含文件扩展名)</param>
            /// <returns></returns>
            public static IServiceCollection RegisterAssembly(this IServiceCollection service, string interfaceAssemblyName, string implementAssemblyName)
            {
                if (service == null)
                    throw new ArgumentNullException(nameof(service));
                if (string.IsNullOrEmpty(interfaceAssemblyName))
                    throw new ArgumentNullException(nameof(interfaceAssemblyName));
                if (string.IsNullOrEmpty(implementAssemblyName))
                    throw new ArgumentNullException(nameof(implementAssemblyName));
    
                var interfaceAssembly = RuntimeService.GetAssembly(interfaceAssemblyName);
                if (interfaceAssembly == null)
                {
                    throw new DllNotFoundException($"the dll "{interfaceAssemblyName}" not be found");
                }
    
                var implementAssembly = RuntimeService.GetAssembly(implementAssemblyName);
                if (implementAssembly == null)
                {
                    throw new DllNotFoundException($"the dll "{implementAssemblyName}" not be found");
                }
    
                //过滤掉非接口及泛型接口
                var types = interfaceAssembly.GetTypes().Where(t => t.GetTypeInfo().IsInterface && !t.GetTypeInfo().IsGenericType);
    
                foreach (var type in types)
                {
                    //过滤掉抽象类、泛型类以及非class
                    var implementType = implementAssembly.DefinedTypes
                        .FirstOrDefault(t => t.IsClass && !t.IsAbstract && !t.IsGenericType &&
                                             t.GetInterfaces().Any(b => b.Name == type.Name));
                    if (implementType != null)
                    {
                        service.AddSingleton(type, implementType.AsType());
                    }
                }
    
                return service;
            }
        }
     public class RuntimeService
        {
            /// <summary>
            /// 获取项目程序集,排除所有的系统程序集(Microsoft.***、System.***等)、Nuget下载包
            /// </summary>
            /// <returns></returns>
            public static IList<Assembly> GetAllAssemblies()
            {
                var list = new List<Assembly>();
                var deps = DependencyContext.Default;
                var libs = deps.CompileLibraries.Where(lib => !lib.Serviceable && lib.Type != "package");//排除所有的系统程序集、Nuget下载包
                foreach (var lib in libs)
                {
                    try
                    {
                        var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(lib.Name));
                        list.Add(assembly);
                    }
                    catch (Exception)
                    {
                        // ignored
                    }
                }
                return list;
            }
    
            public static Assembly GetAssembly(string assemblyName)
            {
                return GetAllAssemblies().FirstOrDefault(assembly => assembly.FullName.Contains(assemblyName));
            }
    
            public static IList<Type> GetAllTypes()
            {
                var list = new List<Type>();
                foreach (var assembly in GetAllAssemblies())
                {
                    var typeInfos = assembly.DefinedTypes;
                    foreach (var typeInfo in typeInfos)
                    {
                        list.Add(typeInfo.AsType());
                    }
                }
                return list;
            }
    
            public static IList<Type> GetTypesByAssembly(string assemblyName)
            {
                var list = new List<Type>();
                var assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(assemblyName));
                var typeInfos = assembly.DefinedTypes;
                foreach (var typeInfo in typeInfos)
                {
                    list.Add(typeInfo.AsType());
                }
                return list;
            }
    
            public static Type GetImplementType(string typeName, Type baseInterfaceType)
            {
                return GetAllTypes().FirstOrDefault(t =>
                {
                    if (t.Name == typeName &&
                        t.GetTypeInfo().GetInterfaces().Any(b => b.Name == baseInterfaceType.Name))
                    {
                        var typeInfo = t.GetTypeInfo();
                        return typeInfo.IsClass && !typeInfo.IsAbstract && !typeInfo.IsGenericType;
                    }
                    return false;
                });
            }
        }
  • 相关阅读:
    Hadoop源代码分析
    Java中如何把两个数组合并为一个
    数据库死锁的解决办法
    Java程序中解决数据库超时与死锁
    mysql 死锁检查
    JDBC事务和数据库事务嵌套的讨论 .
    嵌套事务和事务保存点的错误处理
    java string常见操作题
    java基本数据类型包装类
    java string
  • 原文地址:https://www.cnblogs.com/xuxml/p/12114887.html
Copyright © 2011-2022 走看看