.Net Core动态注入

更方便的注入自己的服务

  • 因由
  • 关于依赖注入
  • 干货
      • 准备枚举和自定义属性
      • 赋予我们实现类属性
      • 然后在ConfigureServices中识别这些接口实现,并加载他们

因由

因为需求,我需要一个间小的服务来处理sokect的数据,但是找到的主流的框架都是分层应用,将个层级模块划分为单独的工程,好比是这样
.Net Core动态注入_第1张图片

但是我只需要几个实体,简单的收发数据,并进行一定的逻辑处理,那么没必要使用那么大的一个项目来实现,所以考虑自己写。

关于依赖注入

在.net core 中引入了依赖注入的思想,并隐隐成为了一种新的设计模式,那么每当我需要注入的时候就得在ConfigureServices中加一句:

services.AddScoped(typeof(ITestRepository), typeof(TestRepository));

当我的项目没有分层的必要,但是又有那么十来个服务需要注入怎么办呢,是在代码里加是多行么?这样不光是显得很臃肿,而且一行行的写总觉得有点不聪明_||,那么想办法赋予他们一个属性,让后自动去加载。

干货

准备枚举和自定义属性

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class AutoInjectAttribute : Attribute
    {
        public AutoInjectAttribute(Type interfaceType, InJectType injectType)
        {
            Type = interfaceType;
            InJectType = injectType;
        }

        public Type Type { get; set; }

        /// 
                /// 注入类型
                /// 
        public InJectType InJectType { get; set; }
    }
    
    public enum InJectType
    {
        Transient,
        Scope,
        Single,
        NoNeed
    }

赋予我们实现类属性

    [AutoInject(typeof(ITestRepository), InJectType.Scope)]
    public class TestRepository : Repository<Test, string>, ITestRepository
    {
        public TestRepository(DefaultDbContext dbContext) : base(dbContext)
        {
        }
    }

然后在ConfigureServices中识别这些接口实现,并加载他们

在ConfigureServices实现:

services.RegisterAssembly();

这是实现方法:

        public static IServiceCollection RegisterAssembly(this IServiceCollection services)
        {
            var path = AppDomain.CurrentDomain.BaseDirectory;
            var assemblies = Directory.GetFiles(path, "*.dll").Select(Assembly.LoadFrom).ToList();
            foreach (var assembly in assemblies)
            {
                var types = assembly.GetTypes().Where(a => a.GetCustomAttribute<AutoInjectAttribute>() != null).ToList();
                if (types.Count <= 0) 
                    continue;
                foreach (var type in types)
                {
                    var attr = type.GetCustomAttribute<AutoInjectAttribute>();
                    if (attr?.Type == null) continue;
                    switch (attr.InJectType)
                    {
                        case InJectType.Scope:
                            services.AddScoped(attr.Type, type);
                            break;
                        case InJectType.Single:
                            services.AddSingleton(attr.Type, type);
                            break;
                        case InJectType.Transient:
                            services.AddTransient(attr.Type, type);
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
                }
            }
            return services;
        }

这样我们动态加载的功能就实现了。

你可能感兴趣的:(asp.net,core,1024程序员节,.netcore)