.net6之AutoInjection

概念

依赖注入私有化封装
区别:
AddTransient:每次 service 请求都是获得不同的实例。暂时性模式:暂时性对象始终不同,无论是不是同一个请求(同一个请求里的不同服务)同一个客户端,每次都是创建新的实例。
AddScoped:对于同一个请求返回同一个实例,不同的请求返回不同的实例。作用域模式:作用域对象在一个客户端请求中是相同的,但在多个客户端请求中是不同的。
AddSingleton:每次都是获得同一个实例。单一实例模式:单一实例对象对每个对象和每个请求都是相同的,可以说是不同客户端不同请求都是相同的。
生命周期:
AddSingleton的生命周期:项目启动-项目关闭 相当于静态类 只会有一个。
AddScoped的生命周期:请求开始-请求结束 在这次请求中获取的对象都是同一个。
AddTransient的生命周期:请求获取-(GC回收-主动释放) 每一次获取的对象都不是同一。

项目总览


实现

程序集管理 AssemblyManager

    public static class AssemblyManager
    {
        private static readonly string[] Filters = { "dotnet-", "Microsoft.", "mscorlib", "netstandard", "System", "Windows" };
        private static Assembly[] _allAssemblies;
        private static Type[] _allTypes;

        static AssemblyManager()
        {
            AssemblyFilterFunc = name =>
            {
                return name.Name != null && !Filters.Any(m => name.Name.StartsWith(m));
            };
        }

        /// 设置 程序集过滤器
        /// </summary>
        public static Func<AssemblyName, bool> AssemblyFilterFunc { private get; set; }


        /// <summary>
        /// 获取 所有类型
        /// </summary>
        public static Type[] AllTypes
        {
            get
            {
                if (_allTypes == null)
                {
                    Init();
                }

                return _allTypes;
            }
        }
        /// <summary>
        /// 初始化
        /// </summary>
        public static void Init()
        {
            _allAssemblies = DependencyContext.Default.GetDefaultAssemblyNames().Where(AssemblyFilterFunc).Select(Assembly.Load).ToArray();
            _allTypes = _allAssemblies.SelectMany(m => m.GetTypes()).Distinct().ToArray();
        }

        /// <summary>
        /// 查找指定条件的类型
        /// </summary>
        public static Type[] FindTypes(Func<Type, bool> predicate)
        {
            return AllTypes.Where(predicate).Distinct().ToArray();
        }
    }


AutoInjectionAttribute

 /// <summary>
    /// 自动注入依赖标记
    /// </summary>
    [AttributeUsage(AttributeTargets.Class,Inherited =false)]
    public abstract class AutoInjectionAttribute:Attribute
    {
        /// <summary>
        /// 注入类型
        /// </summary>
        public ServiceLifetime InjectionType { get; }

        protected AutoInjectionAttribute(ServiceLifetime lifestyle) => InjectionType = lifestyle;

        /// <summary>
        /// 注入当前实现接口,默认为true
        /// </summary>
        public bool AddImplementedInterface { get; set; } = true;

        /// <summary>
        /// 尝试添加
        /// </summary>
        public bool TryAdd { get; set; }

        /// <summary>
        /// 是否替换已存在的服务实现
        /// </summary>
        public bool Replace { get; set; }

        /// <summary>
        /// 是否注册自身类型,默认没有接口的类型会注册自身
        /// </summary>
        public bool AddSelf { get; set; }
    }

AutoInjectionMultipleAttribute

  /// <summary>
    /// 标记允许多重注入,即一个接口可以注入多个实例
    /// </summary>
    [AttributeUsage(AttributeTargets.Interface, Inherited = false)]
    public class AutoInjectionMultipleAttribute : Attribute
    {
    }

IgnoreAutoInjectionAttribute

    /// <summary>
    /// 设置此标记类型,将不会被自动添加依赖注册
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, Inherited = false)]
    public class IgnoreAutoInjectionAttribute : Attribute
    {
    }

IInjectionConfiguration

 [IgnoreAutoInjection]
    public interface IInjectionConfiguration
    {
        void Configuration(IServiceCollection services);
    }

IInjectionScoped

    /// <summary>
    /// 实现此接口的类型将被注册为<see cref="ServiceLifetime.Scoped"/>模式
    /// </summary>
    [IgnoreAutoInjection]
    public interface IInjectionScoped
    {
    }

IInjectionSingleton

   /// <summary>
    ///     实现此接口的类型将被注册为<see cref="ServiceLifetime.Singleton">
    /// </summary>
    [IgnoreAutoInjection]
    public interface IInjectionSingleton
    {
    }

IInjectionTransient

    /// <summary>
    /// 实现此接口的类型将被注册为<see cref="ServiceLifetime.Transient"/>模式
    /// </summary>
    [IgnoreAutoInjection]
    public interface IInjectionTransient
    {
    }

ServiceCollectionExtensions(服务封装)

   public static class ServiceCollectionExtensions
    {
        public static IServiceCollection AddAutoInjection(this IServiceCollection services)
        {
          
            Type[] autoInjectionImplementedTypes = FindAutoInjectionImplementedTypes();
            autoInjectionImplementedTypes.Each(implementationType => AddToServiceCollection(services, implementationType));

            foreach (Type module in AssemblyManager.FindTypes(type =>
            type.IsClass && !type.IsAbstract && !type.IsInterface &&
            !type.HasAttribute<IgnoreAutoInjectionAttribute>() && type.GetInterfaces().Contains(typeof(IInjectionConfiguration))))
            {
                ((IInjectionConfiguration)Activator.CreateInstance(module)).Configuration(services);
            }
            return services;

        }

        #region 将服务实现类型注册到服务集合中
        private static void AddToServiceCollection(IServiceCollection services, Type implementationType)
        {
            if (implementationType.IsAbstract || implementationType.IsInterface)
            {
                return;
            }
           ServiceLifetime?  lifetime =GetLifeTimeType(implementationType);
            if (lifetime == null)
            {
                return;
            }
            var injectionAttribute = implementationType.GetAttribute<AutoInjectionAttribute>();

           // implementationType.GetMethods().Each(m =>m.)

            Type[] serviceTypes = (injectionAttribute == null || injectionAttribute.AddImplementedInterface) ? GetTmplementedInterfaces(implementationType) : null;

            //服务数量为0或显示要求注册自身时,注册自身

            if (serviceTypes.HasVal() == false || injectionAttribute?.AddSelf==true)
            {
                services.TryAdd(new ServiceDescriptor(implementationType, implementationType, lifetime.Value));
                if (serviceTypes.HasVal() == false)
                {
                    return;
                }
            }
            if (serviceTypes.Length > 1)
            { 
            List<string> orderTokens=new List<string> { implementationType.Namespace.Substring("",".","") };
            orderTokens.AddIfNotExist("BPA");
                serviceTypes = serviceTypes.OrderByPrefixes(m => m.FullName, orderTokens.ToArray()).ToArray();
            }
            //注册接口服务
            for (int i = 0; i < serviceTypes.Length; i++)
            {
                Type serviceType = serviceTypes[i];
                ServiceDescriptor descriptor = new ServiceDescriptor(serviceType, implementationType, lifetime.Value);
                if (lifetime.Value == ServiceLifetime.Transient)
                {
                    services.TryAddEnumerable(descriptor);
                    continue;
                }
                
                bool multiple = serviceType.HasAttribute<AutoInjectionMultipleAttribute>();
                if (i == 0)
                {
                    if (multiple)
                    {
                        services.Add(descriptor);
                    }
                    else
                    {
                        AddSingleService(services, descriptor, injectionAttribute);
                    }
                }
                else
                {
                    if (multiple)
                    {
                        services.Add(descriptor);
                    }
                    else
                    {
                        //有多个接口,后边的接口注册使用第一个接口的实例,保证同个实现类的多个接口获得同一实例
                        Type firstServiceType = serviceTypes[0];
                        descriptor = new ServiceDescriptor(serviceType, provider => provider.GetService(firstServiceType), lifetime.Value);
                        AddSingleService(services, descriptor, injectionAttribute);
                    }
                }
            }

        }
        #endregion

        #region 查找所有自动注册的服务实现类型

        static Type[] FindAutoInjectionImplementedTypes()
        {
            Type[] types = new[] { typeof(IInjectionScoped), typeof(IInjectionSingleton), typeof(IInjectionTransient) };
            return AssemblyManager.FindTypes(type=>type.IsClass&&!type.IsAbstract&&!type.IsInterface&&
            !type.HasAttribute<IgnoreAutoInjectionAttribute>()&&
            (types.Any(t => t.IsAssignableFrom(type)||type.HasAttribute<AutoInjectionAttribute>(false))));
        }
        #endregion


        #region 获取服务注册生命周期
        static ServiceLifetime? GetLifeTimeType(Type type)
        { 
            var attribute=type.GetAttribute<AutoInjectionAttribute>();
            if (attribute != null)
            {
                return attribute.InjectionType;
            }
            if (type.IsDericeClassFrom<IInjectionTransient> != null)
            {
                return ServiceLifetime.Transient;
            }
            if (type.IsDericeClassFrom<IInjectionScoped> != null)
            {
                return ServiceLifetime.Scoped;
            }
            if (type.IsDericeClassFrom<IInjectionSingleton> != null)
            {
                return ServiceLifetime.Singleton;
            }
            return null;
        }

        #endregion

        #region 获取实现类型的所有可注册服务接口

        static Type[] GetTmplementedInterfaces(Type implementationType)
        {
            Type[] exceptInterfaces = { typeof(IDisposable) };
            Type[] interfaceTypes=implementationType.GetInterfaces().Where(t =>! exceptInterfaces.Contains(t)&&!t.HasAttribute<IgnoreAutoInjectionAttribute>()).ToArray();
            for (int index = 0; index < interfaceTypes.Length; index++)
            { 
            Type interfaceType = interfaceTypes[index];
                if (interfaceType.IsGenericType && !interfaceType.IsGenericTypeDefinition && interfaceType.FullName == null)
                { 
                exceptInterfaces[index] = interfaceType.GetGenericTypeDefinition();
                }
            
            }
            return interfaceTypes;
        }
        #endregion

        #region 注册单例服务
        /// <summary>
        /// 注册单例服务
        /// </summary>
        /// <param name="services"></param>
        /// <param name="descriptor"></param>
        /// <param name="injectionAttribute"></param>
        static void AddSingleService(IServiceCollection services, ServiceDescriptor descriptor, AutoInjectionAttribute injectionAttribute)
        {
            if (injectionAttribute?.Replace == true)
            {
                services.Replace(descriptor);
            }
            else if (injectionAttribute?.TryAdd == true)
            {
                services.TryAdd(descriptor);
            }
            else
            {
                services.Add(descriptor);
            }
        }
        #endregion
    }

打包传送门 https://www.cnblogs.com/inclme/p/16053978.html

.net6中使用

引用上述nuget包

var builder = WebApplication.CreateBuilder(args);
//自动扫描依赖注入
builder.Services.AddAutoInjection();

封装AppService 统一封装数据库上下分封装和参数注入 ORM可替换成其他的

  public abstract class AppService : AppServiceBase<UserIdentityBase>
    {
        public AppService(IServiceProvider serviceProvider) : base(serviceProvider)
        {
            _sqlSugarClient = ResolveService<SqlSugarScope>();
            _configurationModel = ResolveService<IOptions<ConfigurationModel>>();
        }

        protected SqlSugarScope _sqlSugarClient { get; }
        protected IOptions<ConfigurationModel> _configurationModel { get; }
    }

服务自动注入示例


    public interface IAuthorizeService : IInjectionScoped
    {
        Task<JwtInfo> SignInAsync(SignInRequest request);

        Task<UserIdentityResponse> GetUserInfoAsync();
    }

 public class AuthorizeService : AppService, IAuthorizeService
    {
        private readonly IJwtService _jwtService;
        public AuthorizeService(IJwtService jwtService, IServiceProvider serviceProvider) : base(serviceProvider)
        {
            _jwtService = jwtService;
        }
        #region 用户登录
        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<JwtInfo> SignInAsync(SignInRequest request)
        {
            request.Pwd = EncryptHelper.DesEncrypt(request.Pwd, "~1@Aa*<>");
            var token = _jwtService.CreateAccessToken(new BPAUserIdentity()
            {
                Id = IdGenerator.NextId(),
                UserName = request.UserName
            });
            return await Task.FromResult(token);
        }
        #endregion

        #region 获取用户信息
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <returns></returns>
        public async Task<UserIdentityResponse> GetUserInfoAsync()
        {
            
            UserIdentityResponse res = new UserIdentityResponse();
            res.Id = CurrentUser.Id;
            res.UserName = CurrentUser.UserName;
            return await Task.FromResult(res);
        }
        #endregion
    }

  
posted @ 2025-01-08 11:32  小小青年  阅读(20)  评论(0)    收藏  举报