依赖注入

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<string, Lazy<string>> _dicCache = new();      public void Set(string key, string value)     {         _ = _dicCache.AddOrUpdate         (             key,             k => new Lazy<string>(() => value, LazyThreadSafetyMode.ExecutionAndPublication),             (_, _) => new Lazy<string>(() => 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

商匡云商
Logo
注册新帐户
对比商品
  • 合计 (0)
对比
0
购物车