.NET Core中实现自动注入、批量注入

15 篇文章 0 订阅

我们在使用AddScoped、AddTransient、AddSingleton这类方法的时候很是麻烦。我们每增加一个接口以及其实现的时候,是不是需要在这里硬编码注册一行代码呢?项目小还好,但当我们的项目变得庞大之后,这里的依赖注入怎么来维护呢?
在网上翻了半天,看了很多方法,其实现代码感觉都很不优雅,想想还是自己写一个比较实用吧,我们只需按照一个规定来定义和实现接口。应用程序就能自动扫描并注册这些程序集中的接口和对应实现类,完成依赖注入的自动注册,具体的实现可以通过接口或特性来实现,具体实现如下: 

第一步:创建如下这样空接口,用于标记需要注入

public interface IDependency
{
}
/// <summary>
/// 实现该接口将自动注册到Ioc容器,生命周期为每次请求创建一个实例
/// </summary>
public interface IScopeDependency: IDependency
{
}
/// <summary>
/// 实现该接口将自动注册到Ioc容器,生命周期为单例
/// </summary>
public interface ISingletonDependency : IDependency
{
}
/// <summary>
/// 实现该接口将自动注册到Ioc容器,生命周期为每次创建一个新实例
/// </summary>
public interface ITransientDependency : IDependency
{
}

第二步:创建需要注入的功能接口,这类接口就是你想实现某些功能的封装,它们都继承第一步创建的标记接口,如下,我创建一个功能接口

public interface IUserService: IScopeDependency
{
}

第三步:实现需要注入的功能接口,如下,我创建了一个实现UserService的类

public class UserService: IUserService
{
}

 第四步:扩展IServiceCollection批量注入方法AddDataService

/// <summary>
/// 要扫描的程序集名称
/// 默认为[^Shop.Utils|^Shop.]多个使用|分隔
/// </summary>
public static string MatchAssemblies = "^Shop.Utils|^Shop.";

public static IServiceCollection AddDataService(this IServiceCollection services)
{
    #region 依赖注入
    //services.AddScoped<IUserService, UserService>();           
    var baseType = typeof(IDependency);
    var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
    var getFiles = Directory.GetFiles(path, "*.dll").Where(Match);  //.Where(o=>o.Match())
    var referencedAssemblies = getFiles.Select(Assembly.LoadFrom).ToList();  //.Select(o=> Assembly.LoadFrom(o))         

    var ss = referencedAssemblies.SelectMany(o => o.GetTypes());

    var types = referencedAssemblies
        .SelectMany(a => a.DefinedTypes)
        .Select(type => type.AsType())
        .Where(x => x != baseType && baseType.IsAssignableFrom(x)).ToList();
    var implementTypes = types.Where(x => x.IsClass).ToList();
    var interfaceTypes = types.Where(x => x.IsInterface).ToList();
    foreach (var implementType in implementTypes)
    {
        if (typeof(IScopeDependency).IsAssignableFrom(implementType))
        {
            var interfaceType = interfaceTypes.FirstOrDefault(x => x.IsAssignableFrom(implementType));
            if (interfaceType != null)
                services.AddScoped(interfaceType, implementType);
        }
        else if(typeof(ISingletonDependency).IsAssignableFrom(implementType))
        {
            var interfaceType = interfaceTypes.FirstOrDefault(x => x.IsAssignableFrom(implementType));
            if (interfaceType != null)
                services.AddSingleton(interfaceType, implementType);
        }
        else
        {
            var interfaceType = interfaceTypes.FirstOrDefault(x => x.IsAssignableFrom(implementType));
            if (interfaceType != null)
                services.AddTransient(interfaceType, implementType);
        }
    }
    #endregion
    return services;
}

/// <summary>
/// 程序集是否匹配
/// </summary>
public static bool Match(string assemblyName)
{
    assemblyName = Path.GetFileName(assemblyName);
    if (assemblyName.StartsWith($"{AppDomain.CurrentDomain.FriendlyName}.Views"))
        return false;
    if (assemblyName.StartsWith($"{AppDomain.CurrentDomain.FriendlyName}.PrecompiledViews"))
        return false;
    return Regex.IsMatch(assemblyName, MatchAssemblies, RegexOptions.IgnoreCase | RegexOptions.Compiled);
}

第四步:在Startup.cs调用AddDataService方法进行批量注入

 

public void ConfigureServices(IServiceCollection services)
{          
    services.AddDataService();
}

测试

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡老汉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值