.NET 幫助

Autofac .NET 6(開發人員如何使用)

發佈 2024年7月1日
分享:

在 .NET 開發領域,有效地管理相依性對於建立可擴展、可維護和可測試的應用程式至關重要。 依賴注入(數字輸入)容器透過實現控制反轉在達成這些目標中扮演了關鍵角色(控制反轉)原則。 在眾多可用的通用託管機制庫中,Autofac 作為一個功能豐富且可擴展的 .NET 框架脫穎而出。

在本文中,我們將展開一段探索Autofac .NET 6的旅程,闡明其功能和優勢,以展示其使用的實際範例。 在本文的後面部分,我們將學習IronPDF,一個來自Iron Software的強大PDF生成庫。 我們也將展示一個使用案例,其中 Autofac.NET 和 IronPDF 一同使用。

理解 Autofac .NET

Autofac 是一個開源的 .NET IoC 容器,為像 Web API 這樣的應用程序提供全面的依賴注入和組件註冊支援。由 Nicholas Blumhardt 開發並由一個專注的社群維護,Autofac 提供了一個強大而靈活的解決方案來管理物件生命週期、解決依賴關係以及組合應用程式元件。

如需進一步了解Autofac如何增強您的.NET應用程式,請考慮探索由Iron Software提供的資源。IronPDF 的 .NET PDF 資料庫,重點介紹了 PDF 生成和操作的高級功能。 您還可以深入了解IronBarcode 的 .NET 條碼庫查看條形碼生成中依賴注入的實際應用。

通過訪問以獲取更多使用Autofac在實際場景中的深入見解和實際案例。IronSoftware 的官方頁面,您將找到一整套產品,如 IronOCR 和 IronXL,這些產品可以完美結合 Autofac 並提升您的 .NET 開發過程。

Autofac 的特點

  1. 容器構建和元件註冊:您可以透過在啟動類別中註冊元件來使用Autofac構建容器。 您可以使用 lambda 表達式、類型或預建的實例來註冊元件。
    public class Startup
    {
        public void ConfigureContainer()
        {
            var builder = new ContainerBuilder(); // host sub property builder
            builder.RegisterInstance(new TaskRepository()).As<ITaskRepository>();
            builder.RegisterType<TaskController>();
            builder.Register(c => new LogManager(DateTime.Now)).As<ILogger>();
            // Scan an assembly for components
            builder.RegisterAssemblyTypes(myAssembly).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces();
            var container = builder.Build();
        }
    }
    public class Startup
    {
        public void ConfigureContainer()
        {
            var builder = new ContainerBuilder(); // host sub property builder
            builder.RegisterInstance(new TaskRepository()).As<ITaskRepository>();
            builder.RegisterType<TaskController>();
            builder.Register(c => new LogManager(DateTime.Now)).As<ILogger>();
            // Scan an assembly for components
            builder.RegisterAssemblyTypes(myAssembly).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces();
            var container = builder.Build();
        }
    }
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#
  1. 表達依賴性:Autofac 可以注入建構函數參數、處理屬性注入和方法注入。
    public class TaskController
    {
        private ITaskRepository _repository;
        private ILogger _logger;

        public TaskController(ITaskRepository repository, ILogger logger)
        {
            this._repository = repository;
            this._logger = logger;
        }
    }
    public class TaskController
    {
        private ITaskRepository _repository;
        private ILogger _logger;

        public TaskController(ITaskRepository repository, ILogger logger)
        {
            this._repository = repository;
            this._logger = logger;
        }
    }
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#
  1. 靈活的模組系統:Autofac 模組在 XML 配置與代碼註冊之間達成平衡。 您可以在代碼中指定複雜的註冊,或使用 XML 更改部署時的行為。
    public class CarTransportModule : Module
    {
        public bool ObeySpeedLimit { get; set; }

        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<Car>().As<IVehicle>();
            if (ObeySpeedLimit)
                builder.RegisterType<SaneDriver>().As<IDriver>();
            else
                builder.RegisterType<CrazyDriver>().As<IDriver>();
        }
    }
    public class CarTransportModule : Module
    {
        public bool ObeySpeedLimit { get; set; }

        protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<Car>().As<IVehicle>();
            if (ObeySpeedLimit)
                builder.RegisterType<SaneDriver>().As<IDriver>();
            else
                builder.RegisterType<CrazyDriver>().As<IDriver>();
        }
    }
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#
  1. 簡單擴展點: Autofac 提供激活事件以自定義元件的激活或釋放。
    var builder = new ContainerBuilder();
    builder.RegisterType<Listener>().As<IListener>().OnActivated(e => e.Instance.StartListening());
    builder.RegisterType<Processor>().OnActivating(e => e.Instance.Initialize());
    var container = builder.Build();
    var builder = new ContainerBuilder();
    builder.RegisterType<Listener>().As<IListener>().OnActivated(e => e.Instance.StartListening());
    builder.RegisterType<Processor>().OnActivating(e => e.Instance.Initialize());
    var container = builder.Build();
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

Autofac.NET 的主要功能

  1. 靈活的元件註冊:Autofac允許開發人員使用各種註冊技術來註冊元件,包括手動註冊、組件掃描和基於屬性的註冊。 這種靈活性使得可以對組件的實例化和配置進行細粒度控制。

  2. 生命週期管理:Autofac 支持多種物件生命週期範圍,包括單例模式(singleton)、每次依賴(instance per dependency)、每次生命週期範圍(instance per lifetime scope)和每次請求(instance per request)。對物件生命週期的這種細緻控制可確保資源的有效利用,並防止長時間運行的應用程序中出現記憶體洩漏。

  3. 自動依賴解析:Autofac 會根據已註冊的元件註冊及其依賴項自動解析依賴。 這個自動化連線簡化了複雜物件圖的配置,並促進元件之間的鬆散耦合。

  4. 模組組成:Autofac 允許開發人員使用模組來組織和封裝組件註冊。 模組作為相關註冊的邏輯容器,使得管理和維護具有多個元件的大型應用程式變得更容易。

  5. 攔截和面向方面編程 (面向方面程式設計):Autofac 提供攔截和面向方面編程的支持。(面向方面程式設計)透過其截取擴充套件。 透過攔截,開發人員可以將日誌記錄、快取和安全等橫切關注點應用於組件,而不需修改其實現。

  6. ASP.NET Core 和 .NET Core 整合:Autofac 無縫整合 .NET Core 和 ASP.NET Core,為現代網頁應用程式和微服務提供一流的依賴注入支援。 它利用內建的服務提供者抽象來確保與 .NET 生態系統的兼容性和互操作性。

Autofac.NET 的實用範例

讓我們探討一些實際範例來說明Autofac.NET的使用:

public class Program
{
    public static void Main()
    {
        // Setting up Autofac container
        var builder = new ContainerBuilder();

        // Registering types manually
        builder.RegisterType<MyService>().As<IMyService>();

        // Registering types using assembly scanning
        builder.RegisterAssemblyTypes(typeof(MyAssembly).Assembly)
            .Where(t => t.Name.EndsWith("Repository"))
            .AsImplementedInterfaces();

        // Registering modules
        builder.RegisterModule(new MyModule());

        // Building the container
        var container = builder.Build();

        // Resolving dependencies
        using (var scope = container.BeginLifetimeScope())
        {
            var service = scope.Resolve<IMyService>();
            service.DoSomething();
        }
    }
}
public class Program
{
    public static void Main()
    {
        // Setting up Autofac container
        var builder = new ContainerBuilder();

        // Registering types manually
        builder.RegisterType<MyService>().As<IMyService>();

        // Registering types using assembly scanning
        builder.RegisterAssemblyTypes(typeof(MyAssembly).Assembly)
            .Where(t => t.Name.EndsWith("Repository"))
            .AsImplementedInterfaces();

        // Registering modules
        builder.RegisterModule(new MyModule());

        // Building the container
        var container = builder.Build();

        // Resolving dependencies
        using (var scope = container.BeginLifetimeScope())
        {
            var service = scope.Resolve<IMyService>();
            service.DoSomething();
        }
    }
}
Public Class Program
	Public Shared Sub Main()
		' Setting up Autofac container
		Dim builder = New ContainerBuilder()

		' Registering types manually
		builder.RegisterType(Of MyService)().As(Of IMyService)()

		' Registering types using assembly scanning
		builder.RegisterAssemblyTypes(GetType(MyAssembly).Assembly).Where(Function(t) t.Name.EndsWith("Repository")).AsImplementedInterfaces()

		' Registering modules
		builder.RegisterModule(New MyModule())

		' Building the container
		Dim container = builder.Build()

		' Resolving dependencies
		Using scope = container.BeginLifetimeScope()
			Dim service = scope.Resolve(Of IMyService)()
			service.DoSomething()
		End Using
	End Sub
End Class
VB   C#

在本節中,我們展示了Autofac.NET進行依賴注入的實際應用。 從手動註冊到組件掃描和基於模組的註冊,我們已展示了Autofac在管理依賴性方面所提供的靈活性。 通過使用這些技術,開發者可以精簡應用程式的依賴性注入過程,提升可維護性和可擴展性。

若需了解有關 Iron Software 產品如何整合到您的 .NET 應用中以進一步優化和增強功能的更多信息,請探索IronPDF 文件說明在這裡您可以學習如何以編程方式生成和編輯 PDF 文件,或訪問Iron Software 的網站探索各種強大的 .NET 程式庫,如 IronBarcode 用於讀取和寫入條碼,以及 IronOCR 用於高級光學字符識別。

使用Autofac.NET的優點

  1. 簡單和靈活性:Autofac 提供簡單且直觀的 API 用於註冊和解析元件,使依賴注入易於實施和維護。

  2. 測試性和可維護性:透過促進鬆散耦合和依賴反轉,Autofac 增強了 .NET 應用程序的測試性和可維護性,使單元測試和重構變得更加容易。

  3. 性能和可擴展性:Autofac 的輕量化和高效能執行效能使其適用於高效能應用程式和具有大型物件圖的可擴展系統。

  4. 擴展性和自定義:Autofac 的可擴展架構允許開發人員透過自定義模組、註冊源和中介軟體元件來擴展和自定義 Autofac 的行為,以滿足不同應用程式的需求。

  5. 社群與支援:Autofac 擁有活躍的開發者社群和全面的文件,提供了學習、排除錯誤及參與框架貢獻的優秀支援與資源。

Autofac License

Autofac 附帶 MIT 許可證,可免費用於開發和商業用途。

介紹來自Iron Software的IronPDF

Autofac .NET 6(對開發人員的運作方式):圖1 - IronPDF 網頁

IronPDF 是一款強大的 C# PDF 庫,旨在為 .NET 專案中的 PDF 管理提供全面解決方案。 無論您的需求涉及創建、編輯、匯出、保護、加載或操作PDF文檔,IronPDF都有您所需的工具。 以下是其一些突出功能和應用:

-了解更多有關使用IronPDF創建PDF的資訊

-了解如何使用 IronPDF 高效編輯 PDF 文件

-探索 IronPDF 的安全功能

-請造訪 Iron Software 網站以獲取更多詳情。

-查看 IronPDF 文件以獲得深入指導

主要功能

  • HTML 轉 PDF 轉換:輕鬆將 HTML 內容轉換為 PDF。 從 HTML、MVC、ASPX 和圖片生成 PDF。
  • PDF 管理:IronPDF 擁有超過 50 個功能,能讓您簽署、編輯和提取 PDF 內容,使數位簽名和修改變得輕鬆簡便。
  • 跨平台支持:IronPDF 與 C#、F# 和 VB.NET 相容,可在多個 .NET 版本上運行,包括 .NET Core、.NET Standard 和 .NET Framework。 它也適用於 Java、Node.js 和 Python。

    想了解更多關於 IronPDF 如何將 PDF 功能整合到您的專案中,請訪問IronPDF 產品頁面.

    如需全面了解 Iron Software 的產品,包括 IronBarcode、IronOCR 等,請造訪Iron Software 主頁.

相容性和環境

  • .NET 版本:支援 C#、VB.NET 和 F#。
  • 專案類型:適用於網頁(Blazor 和 WebForms 與 IronPDF),桌面(WPF & MAUI),和控制台應用程式。
  • 應用環境:兼容 Windows、Linux、Mac、Docker、Azure、AWS 及更多。
  • IDEs:無縫整合與Microsoft Visual StudioJetBrains Rider.
  • 操作系統和處理器:運行於 Windows、Mac 和 Linux(x64、x86、ARM).

PDF 標準與編輯

  • 相容性:支援各種 PDF 版本(1.2 - 1.7),PDF/UA 和 PDF/A。
  • 自訂:設定 PDF 文件的屬性、安全性和壓縮。
  • 元数据和结构:編輯元数据、修訂歷史和文档结构。
  • 模板與設定:應用頁面模板、頁首、頁尾及頁面設定。

    如需了解這些功能的更多資訊及其實施方法,請造訪IronPDF 官方網站上的詳細 PDF 生成和操作指南.

性能優化

  • 效率:完全支援多執行緒和非同步操作,以實現高效的 PDF 生成。
  • 優先級:專注於準確性、易用性和速度。

    現在讓我們來看看這兩個庫的實際範例。

使用 Autofac.NET 和 IronPDF 生成 PDF 文件

首先,我們來創建一個 Visual Studio 主控台應用程式。

Autofac .NET 6(對於開發人員的運作方式):圖2 - 創建Visual Studio控制台應用程式

提供專案名稱和位置。

Autofac .NET 6(它如何為開發人員工作):圖3 - 配置專案詳情

接下來的步驟是選擇所需的 .NET 版本,然後點擊建立。

然後從 Visual Studio 套件管理器中的 NuGet 套件安裝 IronPDF 庫。

Autofac .NET 6(開發人員如何使用):圖4 - 安裝必要的 IronPDF 套件

參觀IronPDF 文件檔案了解更多關於如何安裝和使用IronPDF庫的資訊。

從 Visual Studio 套件管理器的 NuGet 套件中安裝 Autofac

Autofac .NET 6(對開發人員的工作原理):圖 5 - 安裝必要的 Autofac 套件

了解有關Autofac的更多資訊,請訪問Autofac 文件頁面.

程式碼範例:Autofac 和 IronPDF

using Autofac;
using CacheManager.Core;
using IronPdf;
using System.Reflection;

namespace IronPdfDemos
{
    public class AutoFac
    {
        public static void Execute()
        {
            // Instantiate Cache and ChromePdfRenderer
            var renderer = new ChromePdfRenderer();
            var cache = CacheFactory.Build("ironPdfAutofac", settings =>
            {
                settings.WithDictionaryHandle();
            });

            // Prepare HTML content
            var content = "<h1>Demonstrate Autofac with IronPDF</h1>";
            content += "<p>This is an illustration of using Autofac for dependency injection and IronPDF for generating PDF documents.</p>";
            content += "<h2>Setting up Autofac container</h2>";

            // Setting up Autofac container
            var builder = new ContainerBuilder();
            content += "<p>var builder = new ContainerBuilder();</p>";

            content += "<h2>Registering types manually</h2>";
            // Registering types manually
            builder.RegisterType<MyService>().As<IMyService>();
            content += "<p>builder.RegisterType<MyService>().As<IMyService();</p>";

            content += "<h2>Registering types using assembly scanning</h2>";
            // Registering types using assembly scanning
            builder.RegisterAssemblyTypes(typeof(AutoFac).Assembly)
                .Where(t => t.Name.EndsWith("Repository"))
                .AsImplementedInterfaces();
            content += "<p>builder.RegisterAssemblyTypes(typeof(AutoFac).Assembly).Where(t => t.Name.EndsWith(\"Repository\")).AsImplementedInterfaces();</p>";

            content += "<h2>Registering modules</h2>";
            // Registering modules
            builder.RegisterModule(new MyModule());
            content += "<p>builder.RegisterModule(new MyModule());</p>";

            content += "<h2>Building the container</h2>";
            // Building the container
            var container = builder.Build();
            content += "<p>var container = builder.Build();</p>";

            content += "<h2>Resolving dependencies</h2>";
            // Resolving dependencies
            using (var scope = container.BeginLifetimeScope())
            {
                var service = scope.Resolve<IMyService>();
                service.DoSomething();
            }
            content += "<p>var service = scope.Resolve<IMyService();</p>";

            // Create a PDF from the HTML string using C#
            var pdf = renderer.RenderHtmlAsPdf(content);
            // Export to a file or Stream
            pdf.SaveAs("autofac.pdf");
            Console.WriteLine("We are done...");
            Console.ReadKey();
        }
    }

    internal interface IMyService
    {
        void DoSomething();
    }

    internal class MyModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            // Register module dependencies here
        }
    }

    internal class MyService : IMyService
    {
        public void DoSomething()
        {
            Console.WriteLine("DoSomething");
        }
    }
}
using Autofac;
using CacheManager.Core;
using IronPdf;
using System.Reflection;

namespace IronPdfDemos
{
    public class AutoFac
    {
        public static void Execute()
        {
            // Instantiate Cache and ChromePdfRenderer
            var renderer = new ChromePdfRenderer();
            var cache = CacheFactory.Build("ironPdfAutofac", settings =>
            {
                settings.WithDictionaryHandle();
            });

            // Prepare HTML content
            var content = "<h1>Demonstrate Autofac with IronPDF</h1>";
            content += "<p>This is an illustration of using Autofac for dependency injection and IronPDF for generating PDF documents.</p>";
            content += "<h2>Setting up Autofac container</h2>";

            // Setting up Autofac container
            var builder = new ContainerBuilder();
            content += "<p>var builder = new ContainerBuilder();</p>";

            content += "<h2>Registering types manually</h2>";
            // Registering types manually
            builder.RegisterType<MyService>().As<IMyService>();
            content += "<p>builder.RegisterType<MyService>().As<IMyService();</p>";

            content += "<h2>Registering types using assembly scanning</h2>";
            // Registering types using assembly scanning
            builder.RegisterAssemblyTypes(typeof(AutoFac).Assembly)
                .Where(t => t.Name.EndsWith("Repository"))
                .AsImplementedInterfaces();
            content += "<p>builder.RegisterAssemblyTypes(typeof(AutoFac).Assembly).Where(t => t.Name.EndsWith(\"Repository\")).AsImplementedInterfaces();</p>";

            content += "<h2>Registering modules</h2>";
            // Registering modules
            builder.RegisterModule(new MyModule());
            content += "<p>builder.RegisterModule(new MyModule());</p>";

            content += "<h2>Building the container</h2>";
            // Building the container
            var container = builder.Build();
            content += "<p>var container = builder.Build();</p>";

            content += "<h2>Resolving dependencies</h2>";
            // Resolving dependencies
            using (var scope = container.BeginLifetimeScope())
            {
                var service = scope.Resolve<IMyService>();
                service.DoSomething();
            }
            content += "<p>var service = scope.Resolve<IMyService();</p>";

            // Create a PDF from the HTML string using C#
            var pdf = renderer.RenderHtmlAsPdf(content);
            // Export to a file or Stream
            pdf.SaveAs("autofac.pdf");
            Console.WriteLine("We are done...");
            Console.ReadKey();
        }
    }

    internal interface IMyService
    {
        void DoSomething();
    }

    internal class MyModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            // Register module dependencies here
        }
    }

    internal class MyService : IMyService
    {
        public void DoSomething()
        {
            Console.WriteLine("DoSomething");
        }
    }
}
Imports Autofac
Imports CacheManager.Core
Imports IronPdf
Imports System.Reflection

Namespace IronPdfDemos
	Public Class AutoFac
		Public Shared Sub Execute()
			' Instantiate Cache and ChromePdfRenderer
			Dim renderer = New ChromePdfRenderer()
			Dim cache = CacheFactory.Build("ironPdfAutofac", Sub(settings)
				settings.WithDictionaryHandle()
			End Sub)

			' Prepare HTML content
			Dim content = "<h1>Demonstrate Autofac with IronPDF</h1>"
			content &= "<p>This is an illustration of using Autofac for dependency injection and IronPDF for generating PDF documents.</p>"
			content &= "<h2>Setting up Autofac container</h2>"

			' Setting up Autofac container
			Dim builder = New ContainerBuilder()
			content &= "<p>var builder = new ContainerBuilder();</p>"

			content &= "<h2>Registering types manually</h2>"
			' Registering types manually
			builder.RegisterType(Of MyService)().As(Of IMyService)()
			content &= "<p>builder.RegisterType<MyService>().As<IMyService();</p>"

			content &= "<h2>Registering types using assembly scanning</h2>"
			' Registering types using assembly scanning
			builder.RegisterAssemblyTypes(GetType(AutoFac).Assembly).Where(Function(t) t.Name.EndsWith("Repository")).AsImplementedInterfaces()
			content &= "<p>builder.RegisterAssemblyTypes(typeof(AutoFac).Assembly).Where(t => t.Name.EndsWith(""Repository"")).AsImplementedInterfaces();</p>"

			content &= "<h2>Registering modules</h2>"
			' Registering modules
			builder.RegisterModule(New MyModule())
			content &= "<p>builder.RegisterModule(new MyModule());</p>"

			content &= "<h2>Building the container</h2>"
			' Building the container
			Dim container = builder.Build()
			content &= "<p>var container = builder.Build();</p>"

			content &= "<h2>Resolving dependencies</h2>"
			' Resolving dependencies
			Using scope = container.BeginLifetimeScope()
				Dim service = scope.Resolve(Of IMyService)()
				service.DoSomething()
			End Using
			content &= "<p>var service = scope.Resolve<IMyService();</p>"

			' Create a PDF from the HTML string using C#
			Dim pdf = renderer.RenderHtmlAsPdf(content)
			' Export to a file or Stream
			pdf.SaveAs("autofac.pdf")
			Console.WriteLine("We are done...")
			Console.ReadKey()
		End Sub
	End Class

	Friend Interface IMyService
		Sub DoSomething()
	End Interface

	Friend Class MyModule
		Inherits Module

		Protected Overrides Sub Load(ByVal builder As ContainerBuilder)
			' Register module dependencies here
		End Sub
	End Class

	Friend Class MyService
		Implements IMyService

		Public Sub DoSomething() Implements IMyService.DoSomething
			Console.WriteLine("DoSomething")
		End Sub
	End Class
End Namespace
VB   C#

程式碼說明

讓我們分解您提供的程式碼片段:

  1. ChromePdfRenderer 設置

    • 該代碼初始化了一個 ChromePdfRenderer 實例,用於從 HTML 內容中渲染 PDF,這是 的一個關鍵功能IronPDF.
  2. HTML內容準備

    • content 變數是一個 HTML 字串,用於生成 PDF。

    • 它包含一個 <h1> 標籤,標題為 "Demonstrate Autofac with IronPDF"。
  3. 設定 Autofac 容器

    • 代碼創建了一個名為 builderContainerBuilder 實例。

    • 這是設置 Autofac 容器以進行依賴注入的第一步。
  4. 手動註冊類型

    • 它將類型 MyService 註冊為 IMyService 介面的實現。

    • 這允許 Autofac 在需要時解析依賴項。
  5. 使用程序集掃描註冊類型

    • 它掃描包含 AutoFac 類型的程序集。

    • 註冊名稱以「Repository」結尾的類型作為其相應接口的實現。
  6. 註冊模組

    • 它註冊了一個名為 MyModule 的模組。

    • 模組允許將相關的註冊進行分組。
  7. 構建容器

    • 容器是使用已註冊的組件透過builder.Build構建的。()` 方法。
  8. 解決依賴項問題

    • 在生命週期範圍內(使用(```C# var scope = container.BeginLifetimeScope ```())``` ```), 它解析了一個IMyService` 的實例。
    • 已對解析的服務調用 DoSomething 方法。
  9. PDF 產生:

    • PDF是使用ChromePdfRenderer從內容創建的。

    • 生成的 PDF 被保存為 "autofac.pdf"。

輸出

Autofac .NET 6(開發人員如何運作):圖6 - 前一個代碼範例輸出的PDF

IronPDF 授權

IronPDF需要許可證金鑰。 將授權密鑰放置在 appSettings.json 文件中,如下所示。

{
  "IronPdf.License.LicenseKey": "The Key Here"
}
< 上一頁
OpenTelemetry .NET(對開發人員的運作方式)
下一個 >
Papercut SMTP C#(開發人員如何使用)

準備開始了嗎? 版本: 2024.12 剛剛發布

免費 NuGet 下載 總下載次數: 11,622,374 查看許可證 >