zoukankan      html  css  js  c++  java
  • DotNetCore自带Ioc使用程序集名称注入

    ASP.NET Core本身已经集成了一个轻量级的IOC容器,开发者只需要定义好接口后,在Startup.cs的ConfigureServices方法里使用对应生命周期的绑定方法即可, 常用的有如下三种方法:

       services.AddTransient<IApplicationService,ApplicationService> 

    services.AddScoped<IApplicationService,ApplicationService>
    
    services.AddSingleton<IApplicationService,ApplicationService> 
    • Transient
      Transient 服务在每次请求时被创建,它最好被用于轻量级无状态服务(如我们的Repository和ApplicationService服务)
    • Scoped
      Scoped 服务在每次请求时被创建,生命周期横贯整次请求
    • Singleton 顾名思义,Singleton(单例) 服务在第一次请求时被创建(或者当我们在ConfigureServices中指定创建某一实例并运行方法),其后的每次请求将沿用已创建服务。如果开发者的应用需要单例服务情景,请设计成允许服务容器来对服务生命周期进行操作,而不是手动实现单例设计模式然后由开发者在自定义类中进行操作。

    但是一旦项目变的大 ,要注入的也就很多了,如果一个个添加会十分麻烦,于是可以利用找到程序集里所有需要注入的接口及其实现实现注入。

    首先添加一个 IocRegisterAttribute 特性 

    using System;
    
    namespace DotNetCoreWeb.Attribute
    {
        public class IocRegisterAttribute:System.Attribute
        {
            public Type RegisterType { get; private set; }
    
            public string Name { get; private set; }
    
            public IocRegisterAttribute() : this(null, null)
            {
            }
    
            public IocRegisterAttribute(Type register_type) : this(register_type, null)
            {
            }
    
            public IocRegisterAttribute(string name) : this(null, name)
            {
            }
    
            public IocRegisterAttribute(Type registerType, string name)
            {
                this.RegisterType = registerType;
                this.Name = name;
            }
        }
    }

    其用法是在指定的类上加上,便于搜素程序集时注入需要注入的实例。

    下面写具体的通过程序集名称注入方法:使用扩展方法

      

    /// <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[] IocAssemblyNames)
            {
                 foreach(var name in IocAssemblyNames){
                     RegisterType(name,service);
                 }
                return service;
            }
      
    
            public static void RegisterType(string assemblyName, IServiceCollection service)
            {
                Type[] types = Assembly.Load(assemblyName).GetTypes();
                foreach (Type type in types)
                {
                    System.Attribute[] attrs = System.Attribute.GetCustomAttributes(type);
                    foreach (System.Attribute attr in attrs)
                    {
                        if (attr is IocRegisterAttribute)
                        {
                            var attribute = attr as IocRegisterAttribute;
                            var baseTypes = new List<Type>();
                            if (attribute.RegisterType != null)
                            {
                                baseTypes.Add(attribute.RegisterType);
                            }
                            else if (type.GetInterfaces().Any())
                            {
                                baseTypes.AddRange(type.GetInterfaces());
                            }
                            if (type.BaseType != null && type.BaseType != typeof (Object))
                            {
                                Type bt = type.BaseType;
                                while (bt.BaseType != null && bt.BaseType != typeof (Object))
                                    bt = bt.BaseType;
                                baseTypes.Add(bt);
                            }
                            if (baseTypes.Count <= 0)
                                throw new Exception(string.Format("类型"{0}"没有基类型", type));
                            foreach (Type baseType in baseTypes)
                            { 
                                service.AddTransient(baseType,type);
                            }
                        }
                    }
                }
            }
    
            
        }

    只需在Startup中调用

     

    IocAssemblyName在appsettiings中定义,如果多个程序集则用','隔开。

  • 相关阅读:
    第四周总结&实验报告二
    实验报告 一
    周总结
    期末总结
    第十二周作业
    第十一周作业
    第十周作业
    第九周作业
    第八周作业
    第五周课程总结&试验报告(三)
  • 原文地址:https://www.cnblogs.com/LIUWEI123/p/8584302.html
Copyright © 2011-2022 走看看