從0到1搭建許可權管理系統系列四 .net8 中Autofac的使用(附原始碼)

陈逸子风發表於2024-09-29

說明

該文章是屬於OverallAuth2.0系列文章,每週更新一篇該系列文章(從0到1完成系統開發)。

該系統文章,我會盡量說的非常詳細,做到不管新手、老手都能看懂。

說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+視覺化流程管理系統。

友情提醒:本篇文章是屬於系列文章,看該文章前,建議先看之前文章,可以更好理解專案結構。

有興趣的朋友,請關注我吧(*^▽^*)。

關注我,學不會你來打我

關於Autofac

雖然微軟有自帶的Ioc框架,但是我想說的是Autofac應該說是我用過的最好的Ioc框架。

它的高效能、靈活性、對Aop的支援,簡直就是開發人員的夢中情人。

autofac,它能有效的降低繁雜系統中,程式碼的耦合度,提高程式碼的可維護性。

不僅如此,它可以輕鬆替換依賴關係,從而提高測試效率。

安裝Autofac

1、在啟動專案中,安裝最新版Autofac和Autofac.Extensions.DependencyInjection。

建立類庫

1、DomainService:領域服務類

2、Infrastructure:基礎設施類

3、CoreDomain:核心領域類

如果你看了該系列每篇文章,你會發現,我們的底層架構,是使用DDD領域驅動模型的設計模式搭建後端。

系統架構如圖所示:

搭建好系統架構,我們開始使用Autofac

建立AutofacPlugIn類檔案

在系統PlugIn檔案中建立AutofacPlugIn類檔案,內容如下:

/// <summary>
/// Autofac外掛
/// </summary>
public class AutofacPlugIn : Autofac.Module
{
    /// <summary>
    /// 重寫Autofac的Load方法
    /// </summary>
    /// <param name="containerBuilder"></param>
    protected override void Load(ContainerBuilder containerBuilder)
    {
        //服務專案程式集
        Assembly service = Assembly.Load("DomainService");
        Assembly intracface = Assembly.Load("Infrastructure");

        //專案必須以xxx結尾
        containerBuilder.RegisterAssemblyTypes(service).Where(n => n.Name.EndsWith("Service") && !n.IsAbstract)
            .InstancePerLifetimeScope().AsImplementedInterfaces();
        containerBuilder.RegisterAssemblyTypes(intracface).Where(n => n.Name.EndsWith("Repository") && !n.IsAbstract)
           .InstancePerLifetimeScope().AsImplementedInterfaces();

    }

}

程式碼解釋:

獲取DomainService和Infrastructure程式集,然後批次注入。

值得注意的是,我們在建立類時,給了限定條件。那就是程式集下面的類,必須以Service和Repository結尾,否則autofac會丟擲錯誤。

當然有以xxx結尾,那必然有以xxx開頭。使用StartsWith輕鬆解決。

在Program組成Autofac

.net8 autofac註冊和以往有點出去,需要在Program中新增如如下程式碼

var builder = WebApplication.CreateBuilder(args);
//自定義Autofac中介軟體
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()).ConfigureContainer<ContainerBuilder>(builder =>
 {
     builder.RegisterModule<AutofacPlugIn>();
 });

經過以上配置,autofac已經配置好,是不是很簡單,接下來測試一下。

使用

在Infrastructure類中建立ISysUserRepository和SysUserRepository倉儲介面及介面實現

結構如下:

內容程式碼如下:

ISysUserRepository

/// <summary>
/// 使用者服務倉儲介面
/// </summary>
public interface ISysUserRepository
{
    /// <summary>
    /// 測試Autofac
    /// </summary>
    /// <returns></returns>
    string TestAutofac();
}

SysUserRepository

  /// <summary>
  /// 使用者服務倉儲介面實現
  /// </summary>
  public class SysUserRepository : ISysUserRepository
  {
      /// <summary>
      /// 測試Autofac
      /// </summary>
      /// <returns></returns>
      public string TestAutofac()
      {
          return "Autofac使用成功";
      }
  }

在DomainService中建立ISysUserService和SysUserService服務介面和實現

結構如下:

內容程式碼如下

ISysUserService

/// <summary>
/// 使用者服務介面
/// </summary>
public interface ISysUserService
{
    /// <summary>
    /// 測試Autofac
    /// </summary>
    /// <returns></returns>
    string TestAutofac();
}

SysUserService

/// <summary>
/// 使用者服務介面實現
/// </summary>
public class SysUserService : ISysUserService
{
    #region 構造例項化

    private readonly ISysUserRepository _sysUserRepository;

    public SysUserService(ISysUserRepository sysUserRepository)
    {
        _sysUserRepository = sysUserRepository;
    }

    #endregion

    /// <summary>
    /// 測試Autofac
    /// </summary>
    /// <returns></returns>
    public string TestAutofac()
    {
        return _sysUserRepository.TestAutofac();
    }
}

測試

在SysUserController控制器中呼叫介面(該控制器,在之前文章中已經建好,沒看之前文章的,隨意見一個webapi的控制器也行)。

程式碼如下:

 #region 構造實列化

 /// <summary>
 /// 使用者服務
 /// </summary>
 public ISysUserService _userService;

 /// <summary>
 /// 建構函式
 /// </summary>
 /// <param name="userService"></param>
 public SysUserController(ISysUserService userService)
 {
     _userService = userService;
 }

 #endregion

 /// <summary>
 /// 獲取Token
 /// </summary>
 /// <param name="userName">使用者名稱</param>
 /// <param name="password">密碼</param>
 [HttpGet]
 [AllowAnonymous]
 public string GetToken(string userName, string password)
 {
     var loginResult = JwtPlugIn.BuildToken(new LoginInput { UserName = userName, Password = password });

     return loginResult.Token ?? string.Empty;
 }

 /// <summary>
 /// 測試Autofac
 /// </summary>
 /// <returns></returns>
 [HttpGet]
 [AllowAnonymous]
 public string TestAutofac() 
 {
   return  _userService.TestAutofac();
 }

上述程式碼中要先透過Autofac來例項化介面。

開啟swagger,開始測試

之前說道,我們的介面必須以xxx結束,那麼現在我們把這個約定改一下,看能否呼叫成功。

修改程式碼如下:

 /// <summary>
 /// 重寫Autofac的Load方法
 /// </summary>
 /// <param name="containerBuilder"></param>
 protected override void Load(ContainerBuilder containerBuilder)
 {
     //服務專案程式集
     Assembly service = Assembly.Load("DomainService");
     Assembly intracface = Assembly.Load("Infrastructure");

     //專案必須以xxx結尾
     containerBuilder.RegisterAssemblyTypes(service).Where(n => n.Name.EndsWith("Service111111111") && !n.IsAbstract)
         .InstancePerLifetimeScope().AsImplementedInterfaces();
     containerBuilder.RegisterAssemblyTypes(intracface).Where(n => n.Name.EndsWith("Repository2222222") && !n.IsAbstract)
        .InstancePerLifetimeScope().AsImplementedInterfaces();

 }

可以看到,我們把以Service、Repository結束改成了Service111111111、Repository2222222,也就是說,我們的領域服務類和基礎倉儲類是不符合改命名規範的,aufofac應該報出錯誤。

測試:

以上就是aufofac在本期內容中的使用。

在接下來的系列中,會使用autofac+aop的結合使用,有興趣的朋友,請部落格園關注、微信關注,感謝觀看。

原始碼地址:https://gitee.com/yangguangchenjie/overall-auth2.0-web-api

幫我Star,謝謝。

有興趣的朋友,請關注我微信公眾號吧(*^▽^*)。

關注我:一個全棧多端的寶藏博主,定時分享技術文章,不定時分享開源專案。關注我,帶你認識不一樣的程式世界

相關文章