於.net core 中有內建原生的 DI container,使得可以使用它的 IOC 機制。
另一種取代原生的 Autofac 套件可以搭配複雜的情境需求之,使不需再重新加上額外的程式碼即可達成IOC機制。
無論哪一種,假使遇到大量的類別模組,都需費時去逐一註冊。那可否有節省時間的方式來批次註冊?
對於.net core 中有內建原生的 DI container ,可以使用 Scrutor 套件來協助幫忙批次註冊。
Autofac 則有提供批次註冊的方法。
[Scrutor]
以範例來展示用法。
先準備好要註冊的類別:
namespace ScrutorProj
{
public interface IUserService { }
public class UserService : IUserService { }
public interface IServiceCase{ }
public class ServiceCase : IServiceCase { }
public interface IServiceCase_A { }
public class ServiceCase_A : IServiceCase_A { }
public interface IServiceCase_B { }
public class ServiceCase_B : IServiceCase_B { }
public interface IServiceCase_C { }
public class ServiceCase_C : IServiceCase_C { }
public interface IServiceCase_D { }
public class ServiceCase_D : IServiceCase_D { }
public interface IServiceCase_E { }
public class ServiceCase_E : IServiceCase_E { }
}
於 .Net Core 中 Startup 註冊 Scrutor :
public void ConfigureServices(IServiceCollection services)
{
services.Scan(scan => scan
.FromAssemblyOf<UserService>()
.AddClasses(classes => classes.Where(t => t.Name.Contains("Case",StringComparison.Ordinal)))
.AsImplementedInterfaces()
.WithTransientLifetime()
);
var list = services.Where(x => x.ServiceType.Namespace.Equals("ScrutorProj", StringComparison.OrdinalIgnoreCase)).ToList();
...
}
首先搜尋 UserService 此類別位於的組件,其實就是專案組件,於此組件找出包含命名中 "Case" 的類別。
AsImplementedInterfaces 表示註冊的類別要對應到它們所繼承的介面。
WithTransientLifetime 則是表示它們的生命週期。
此例所註冊的資訊為以下清單:
Transient,ScrutorProj.ServiceCase,ScrutorProj.IServiceCase
Transient,ScrutorProj.ServiceCase_A,ScrutorProj.IServiceCase_A
Transient,ScrutorProj.ServiceCase_B,ScrutorProj.IServiceCase_B
Transient,ScrutorProj.ServiceCase_C,ScrutorProj.IServiceCase_C
Transient,ScrutorProj.ServiceCase_D,ScrutorProj.IServiceCase_D
Transient,ScrutorProj.ServiceCase_E,ScrutorProj.IServiceCase_E
於 Controller 建構子中可以注入所註冊的對應實體:
private readonly IServiceCase_B _ServiceCase_B;
private readonly IServiceCase_D _ServiceCase_D;
public HomeController(IServiceCase_B ServiceCase_B, IServiceCase_D ServiceCase_D)
{
_ServiceCase_B = ServiceCase_B;
_ServiceCase_D = ServiceCase_D;
}
[Autofac]
準備與上例同樣的類別,與同樣於 HomeController 建構子注入IServiceCase_B、IServiceCase_D 。
差別在於註冊的地方。Autofac註冊的運作可以參考 "Autofac 如何替代 Dot Net Core 的原生DI機制"
這邊直接展示如何批次註冊:
public class AutofacModule : Module
{
protected override void Load(ContainerBuilder builder)
{
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.Name.Contains("Case",System.StringComparison.Ordinal))
.AsImplementedInterfaces();
}
}
註冊Autofac以套件提供的 Autofac.Module 方式,準備好繼承它的 AutofacModule 類別, 覆寫 Load 函式。
首先抓出所執行程式的組件資訊,利用 RegisterAssemblyTypes 的函式將組件傳入註冊。接著 Where會過濾找出包含命名中 "Case" 的類別。
然後 AsImplementedInterfaces 也是 將註冊的類別對應到它們所繼承的介面,然後使用預設的生命週期。
一樣也是達成相同的批次註冊效果: