依照约定的注册

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

依赖接口

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

示例:

public class StorageOptions : ITransientDependency{  }

个性

IgnoreInjection

疏忽注入,用于排除不被主动注入

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

示例:

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 ... 扩大办法.

示例:

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 ... 扩大办法.

示例:

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>();

疾速入门

  • 装置.Net 6.0
  1. 新建单元测试我的项目Assignment.DependencyInjection,抉择MSTest,并装置Masa.Utils.Extensions.DependencyInjection

    dotnet new xunit -o Assignment.DependencyInjectioncd Assignment.DependencyInjectiondotnet 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...

开源地址

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

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

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

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

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

如果你对咱们的 MASA Framework 感兴趣,无论是代码奉献、应用、提 Issue,欢送分割咱们