• 依赖注入


    Masa的依赖注入系统是基于Microsoft的依赖注入扩展库(Microsoft.Extensions.DependencyInjection nuget包)开发的,因此,它的文档在Masa中也是有效的。

    按照约定的注册

    Masa引入了按照约定进行服务注册,依据约定大于配置,开发者无需做任何事,框架会自动完成注册

    依赖接口

    • ISingletonDependency: 注册生命周期为Singleton的服务
    • IScopedDependency: 注册生命周期为Scoped的服务
    • ITransientDependency: 注册生命周期为Transient的服务
    • IAutoFireDependency: 自动触发(与ISingletonDependency、IScopedDependency、ITransientDependency结合使用,在服务自动注册结束后触发一次获取服务操作,仅继承IAutoFireDependency不起作用)

    示例:

    ``` C#
    public class StorageOptions : ITransientDependency
    {
      
    }
    ```
    

    特性

    IgnoreInjection

    忽略注入,用于排除不被自动注入

    • Cascade: 设置为true时,当前类以及子类都不再被自动注册,设置为false,仅当前类不被自动注册(默认false)

    示例:

    ``` C#
    public class BaseService : ISingletonDependency
    {
        public static int Count { get; set; } = 0;
    
        public BaseService()
        {
            Count++;
        }
    
        public BaseService(bool isChildren)
        {
    
        }
    }
    
    [IgnoreInjection]
    public class GoodsBaseService : BaseService
    {
        public GoodsBaseService() : base(true)
        {
        }
    }
    
    public class GoodsService : GoodsBaseService
    {
        public static int GoodsCount { get; set; } = 0;
    
        public GoodsService()
        {
            GoodsCount++;
        }
    }
    ```
    
    折叠

    效果等同于:services.AddSingleton<BaseService>(); services.AddSingleton<GoodsService>();

    Dependency

    配合ISingletonDependency、IScopedDependency、ITransientDependency使用,实现服务仅被注册一次

    • TryRegister: 设置true则仅当服务未注册时才会被注册,类似IServiceCollection的TryAdd ... 扩展方法.

    示例:

    ``` C#
    public interface ICache : ISingletonDependency
    {
        void Set(string key, string value);
    }
    
    [Dependency(TryRegister = true)]
    public class EmptyCache : ICache
    {
        public void Set(string key, string value)
        {
            throw new NotSupportedException($"暂不支持{nameof(Set)}方法");
        }
    }
    
    public class MemoryCache : ICache
    {
        private readonly ConcurrentDictionary> _dicCache = new();
    
        public void Set(string key, string value)
        {
            _ = _dicCache.AddOrUpdate
            (
                key,
                k => new Lazy(() => value, LazyThreadSafetyMode.ExecutionAndPublication),
                (_, _) => new Lazy(() => value, LazyThreadSafetyMode.ExecutionAndPublication)
            ).Value;
        }
    }
    ```
    
    折叠

    效果等同于:services.AddSingleton<ICache, MemoryCache>();

    • ReplaceServices: 设置true则替换之前已经注册过的服务,类似IServiceCollection的Replace ... 扩展方法.

    示例:

    ``` C#
    public interface IEncryptionService : ISingletonDependency
    {
        string MethodName { get; }
    }
    
    [Dependency(ReplaceServices = true)]
    public class Sha1EncryptionService : IEncryptionService
    {
        public string MethodName => "Sha1";
    }
    
    public class Md5EncryptionService : IEncryptionService
    {
        public string MethodName => "Md5";
    }
    ```
    

    效果等同于:services.AddSingleton<IEncryptionService, Sha1EncryptionService>();

    快速入门

    1. 新建单元测试项目Assignment.DependencyInjection,选择MSTest,并安装Masa.Utils.Extensions.DependencyInjection

      dotnet new xunit -o Assignment.DependencyInjection
      cd Assignment.DependencyInjection
      dotnet add package Masa.Utils.Extensions.DependencyInjection --version 0.5.0-preview.2
      
    2. 新建类StorageOptions

      public class StorageOptions : ITransientDependency
      {
        
      }
      
    3. 新建类DITest

      [TestClass]
      public class DITest
      {
          private IServiceCollection _services;
      
          [TestInitialize]
          public void Init()
          {
              _services = new ServiceCollection();
              _services.AddAutoInject();//执行自动注入
          }
      
          [TestMethod]
          public void TestAutoInject()
          {
              Assert.IsTrue(_services.Any<StorageOptions>(ServiceLifetime.Transient));//判断StorageOptions注册成功,且生命周期为Transient
          }
      
          private IServiceProvider ServiceProvider => _services.BuildServiceProvider();
      }
      

    总结

    如果需要使用按照约定自动注册服务,则请记住

    • 根据业务需要,则指定类或接口中实现以下接口
      • ISingletonDependency 单例(项目启动后仅初始化一次)
      • IScopedDependency 请求 (每次请求仅初始化一次)
      • ITransientDependency 瞬时(每次获取都会被初始化)
    • 抽象类不会被自动注册
    • 如果你有一个自定义接口IRepository,且希望接口以及对应的默认实现类RepositoryBase会被自动注册生命周期为Scoped,则接口IRepository应该继承IScopedDependency
      • 如果你希望默认提供的RepositoryBase可以被用户定义的类替换,则应该在RepositoryBase上方增加[Dependency(TryRegister = true)],那用户仅需要实现IRepository即可
      • 或不更改默认提供的RepositoryBase,用户实现IRepository后,并在新的实现类上方增加[Dependency(ReplaceServices = true)]

    本章源码

    Assignment07

    https://github.com/zhenlei520/MasaFramework.Practice

    开源地址

    MASA.BuildingBlocks:https://github.com/masastack/MASA.BuildingBlocks

    MASA.Contrib:https://github.com/masastack/MASA.Contrib

    MASA.Utils:https://github.com/masastack/MASA.Utils

    MASA.EShop:https://github.com/masalabs/MASA.EShop

    MASA.Blazor:https://github.com/BlazorComponent/MASA.Blazor

    如果你对我们的 MASA Framework 感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们

    16373211753064.png

  • 相关阅读:
    【无标题】
    vue+element el-input使用clearable后出现两个关闭图标
    编程资源分享2022
    咚咚咚,你的王国之泪已上线「GitHub 热点速览」
    静态代理、动态代理与Mybatis的理解
    芯片验证就是一次旅行
    B001-springcloud alibaba 微服务介绍
    Cocos 进度条物体跟随效果
    制作一个简单HTML大学生抗疫感动专题网页(HTML+CSS)
    1070 Mooncake
  • 原文地址:https://www.cnblogs.com/zhenlei520/p/16497621.html