iT邦幫忙

2022 iThome 鐵人賽

DAY 27
1
自我挑戰組

[Dot Net Core](圖解系列與常用套件)系列 第 27

[Dot Net Core](常用套件) 27. 批次註冊至 IOC Container - Scrutor vs Autofac

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20220927/201446148S5a83yhb2.jpg

於.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;
}

https://ithelp.ithome.com.tw/upload/images/20220927/20144614DgVsX4B2HY.jpg

[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 也是 將註冊的類別對應到它們所繼承的介面,然後使用預設的生命週期。

一樣也是達成相同的批次註冊效果:
https://ithelp.ithome.com.tw/upload/images/20220927/20144614vkw7LixtNC.jpg


上一篇
[Dot Net Core](常用套件) 26.套件Autofac於專案中如何快速擴充客製註冊方法
下一篇
[Dot Net Core](常用套件) 28. 抽換類別模組不重啟服務 - 使用Autofac協助研究範例
系列文
[Dot Net Core](圖解系列與常用套件)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言