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中定义,如果多个程序集则用','隔开。

  • 相关阅读:
    《C# to IL》第一章 IL入门
    multiple users to one ec2 instance setup
    Route53 health check与 Cloudwatch alarm 没法绑定
    rsync aws ec2 pem
    通过jvm 查看死锁
    wait, notify 使用清晰讲解
    for aws associate exam
    docker 容器不能联网
    本地运行aws lambda credential 配置 (missing credential config error)
    Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?
  • 原文地址:https://www.cnblogs.com/LIUWEI123/p/8584302.html
Copyright © 2011-2022 走看看