• 一种方便快捷的服务注册方案


    前言#

    随着dotnet的发展,DependencyInjection已经成为基础库的一部分,现在我们的很多新型应用程序很自然地应用了DependencyInjection功能。应用功能越多,往往服务类型数量也随着增加,如果依靠手写代码一个服务一个服务地进行注册则非常麻烦。如果使用特性标记服务,在运行时反射扫描服务并注册服务,不但会增加服务的启动时间,同时在AOT裁剪环境下服务类型由于没有显式的被使用而编译时默认被裁剪掉,从而表现为没有可注册的服务。

    方案设计#

    Annotation + SourceGenerator一种理解的方案,它仍然使用特性来标记服务,不同的是它在编译时使用SourceGenerator技术收集程序集里标记的服务类型,然后在集程序集里增加向DependencyInjection注册所有标记的服务的扩展方法代码。

    经过SourceGenerator之后,和手写代码一个服务一个服务的注册的效果是完全一样的,最终程序在运行时,不再需要反射程序集扫描服务类型,启动速度会更快一丢丢。同时由于这些服务类型都是显式的被调用,所以也适用于AOT裁剪的项目环境,不再担心服务类型默认被裁剪掉。

    方案实现#

    DependencyInjection.Annotation 这是我对上述方案的一种实现,它开源在github上,支持一个实现对应一种或(最)多(6)种服务类型,使用方式也非常简单。

    1 nuget引用#

    Copy
    <PackageReference Include="DependencyInjection.Annotation" Version="1.0.0" />

    2 服务标记#

    Copy
    // 服务类型为MyService自身 [Service(ServiceLifetime.Singleton)] class MyService { }
    Copy
    // 服务类型为IMyService1 [Service(ServiceLifetime.Singleton, typeof(IMyService1))] class MyService : IMyService1 { }
    Copy
    // 服务类型为IMyService1和IMyService2 [Service(ServiceLifetime.Singleton, typeof(IMyService1), typeof(IMyService2))] class MyService : IMyService1, IMyService2, IDisposable { }

    3 服务注册#

    Copy
    builder.Services.Add{AssemblyName}();

    其中{AssemblyName}为包含服务的程序集名。

  • 相关阅读:
    全新模板中心上线!100+模板,销售/HR/运营/产品……开箱即用!
    C语言 操作符
    C++智能指针
    UDP套接字编程详解
    【C语言】通讯录联系(文件版)
    参数校验与国际化:提高代码稳定性和可维护性的重要方法
    .NET Framework
    监督学习的介绍
    测试开发基础——测试用例的设计
    vue3-布局右侧标签
  • 原文地址:https://www.cnblogs.com/kewei/p/17639269.html