Hướng dẫn tích hợp .NET Aspire vào ứng dụng .NET có sẵn

Có một quan niệm sai lầm phổ biến cho rằng .NET Aspire chỉ dành cho các dự án mới, nhưng một phần quan trọng trong thiết kế của nó chính là khả năng được thêm vào các ứng dụng .NET hiện có.

Cách tiếp cận không xâm lấn này cho phép các nhà phát triển áp dụng dần dần những lợi ích của Aspire, chẳng hạn như điều phối thống nhất và khả năng quan sát được cải thiện, mà không cần viết lại codebase hiện có. Quá trình này tập trung vào việc giới thiệu một dự án mới hoạt động như một mặt phẳng điều khiển cho giải pháp của bạn, đơn giản hóa việc quản lý các microservice, container và các phụ thuộc khác hiện có.

Vấn đề mà Aspire giải quyết cho ứng dụng hiện có

Hãy xem xét một ứng dụng phân tán hiện có điển hình. Bạn có thể có nhiều dự án .NET – Web API, front-end, background worker – mỗi dự án có riêng file launchSettings.json. Ngoài ra, ứng dụng của bạn có thể phụ thuộc vào các dịch vụ bên ngoài như Redis cache hoặc cơ sở dữ liệu PostgreSQL, mà bạn hiện đang quản lý thủ công bằng một file docker-compose.yml riêng biệt.

Cách thiết lập này gây ra một số vấn đề phổ biến:

  • Khởi động thủ công: Bạn phải mở nhiều cửa sổ terminal hoặc cấu hình các dự án khởi động phức tạp trong Visual Studio để mọi thứ hoạt động.
  • Quản lý phụ thuộc: Bạn phải đảm bảo theo cách thủ công rằng các container đang chạy và các chuỗi kết nối, biến môi trường của chúng được định cấu hình chính xác cho từng dịch vụ.
  • Quan sát phân tán: Logs, metrics và traces bị phân tán trên các console khác nhau, gây khó khăn cho việc debug sự cố phân tán.

Thêm Aspire vào giải pháp hiện có này giải quyết các vấn đề trên bằng cách tập trung hóa toàn bộ quy trình. Thay vì quản lý một tập hợp các dịch vụ rời rạc, bạn sẽ quản lý một bộ điều phối Aspire duy nhất xử lý mọi thứ cho bạn.

Hướng dẫn từng bước thêm Aspire

Quá trình thêm Aspire vào giải pháp hiện có khá đơn giản và có thể thực hiện được bằng một vài lệnh.

Bước 1. Cài đặt .NET Aspire Workload

Đầu tiên, đảm bảo bạn đã cài đặt .NET Aspire workload trên máy của mình. Đây là điều kiện tiên quyết để tạo và chạy các dự án Aspire.

dotnet workload install aspire

Bước 2. Thêm dự án AppHost

Cốt lõi của mô hình điều phối Aspire là dự án AppHost. Bạn không trực tiếp sửa đổi các dự án hiện có của mình để thêm Aspire; thay vào đó, bạn thêm một dự án AppHost mới sẽ hoạt động như bộ điều phối cho tất cả các dịch vụ hiện có của bạn.

Từ thư mục gốc của solution của bạn, sử dụng .NET CLI để tạo dự án mới:

dotnet new aspire-apphost -o MyExistingApp.AppHost

Lệnh này tạo một thư mục mới, MyExistingApp.AppHost, chứa một dự án mới với các SDK cần thiết và một file Program.cs.

Bước 3. Tham chiếu các dự án hiện có

Tiếp theo, bạn cần cho dự án AppHost mới biết về các dự án hiện có mà nó sẽ điều phối. Bạn làm điều này bằng cách thêm các tham chiếu dự án, đây là một phần quan trọng trong quy trình làm việc của Aspire.

dotnet sln add MyExistingApp.AppHost/MyExistingApp.AppHost.csproj
dotnet add MyExistingApp.AppHost/MyExistingApp.AppHost.csproj reference MyExistingWebAPI/MyExistingWebAPI.csproj
dotnet add MyExistingApp.AppHost/MyExistingApp.AppHost.csproj reference MyExistingWorker/MyExistingWorker.csproj

Các lệnh này cập nhật các file solution và project, cho phép AppHost “nhìn thấy” các dịch vụ hiện có của bạn.

Bước 4. Điều phối trong file Program.cs của AppHost

Đây là nơi bạn xác định kiến trúc ứng dụng của mình theo cách tiếp cận code-first sạch sẽ. Mở file Program.cs trong dự án AppHost mới của bạn. Bạn sẽ thấy một số mã mẫu cơ bản. Sau đó, bạn sẽ sử dụng phương thức builder.AddProject() để thêm các dự án hiện có của bạn vào mô hình điều phối.

Giả sử ứng dụng của bạn cũng sử dụng Redis cache. Đây là cách bạn điều phối nó:


var builder = DistributedApplication.CreateBuilder(args);

// Thêm dự án web API hiện có vào mô hình điều phối.
var myApi = builder.AddProject<Projects.MyExistingWebAPI>("my-api");

// Thêm phụ thuộc containerized (ví dụ: Redis cache).
var cache = builder.AddRedisContainer("cache");

// Thêm dự án worker hiện có.
var myWorker = builder.AddProject<Projects.MyExistingWorker>("my-worker")
.WithReference(cache); // Worker cần tham chiếu đến cache.

// Bạn có thể thêm nhiều dự án và kết nối các phụ thuộc của chúng.
var myWebUI = builder.AddProject<Projects.MyExistingWebUI>("my-web-ui")
.WithReference(myApi); // Web UI cần gọi API.

// Điều này sẽ build và chạy toàn bộ ứng dụng được điều phối.
builder.Build().Run();

Trong mã này, bạn đã khai báo sự tồn tại của các dự án hiện có của mình (MyExistingWebAPI, MyExistingWorker, v.v.) và một tài nguyên được quản lý mới (Redis). Lời gọi .WithReference() là nơi ma thuật xảy ra: Aspire tự động lo việc inject chuỗi kết nối chính xác cho Redis container vào dự án MyExistingWorker của bạn.

Bước 5. Chạy ứng dụng

Cuối cùng, tất cả những gì cần làm là chạy ứng dụng. Đặt dự án MyExistingApp.AppHost làm dự án startup và nhấn F5 trong Visual Studio, hoặc chạy lệnh sau từ terminal:

dotnet run --project MyExistingApp.AppHost

Aspire bây giờ sẽ tiếp quản. Nó sẽ khởi động Redis container, chạy các dự án Web API và worker hiện có của bạn, và tự động cung cấp cho chúng cấu hình cần thiết. Nó cũng khởi chạy Aspire Dashboard trong trình duyệt của bạn, cung cấp chế độ xem thống nhất về trạng thái, logs và phụ thuộc của ứng dụng.

Điều gì đang xảy ra bên dưới?

Sự đơn giản của quy trình này được thực hiện nhờ một số cơ chế thông minh:

  • Inject biến môi trường: Aspire không sửa đổi mã dự án của bạn để thêm phụ thuộc. Thay vào đó, nó sử dụng một mẫu cấu hình .NET tiêu chuẩn. Khi một tài nguyên được quản lý bởi Aspire được tham chiếu bởi một dự án, Aspire tự động tạo và đặt các biến môi trường phù hợp. Trình cung cấp IConfiguration tiêu chuẩn trong ứng dụng .NET hiện có của bạn sau đó sẽ tự động nhận các biến này, cung cấp chuỗi kết nối hoặc URL dịch vụ chính xác.
  • Khám phá dịch vụ: Khi bạn thêm một dự án với builder.AddProject(), Aspire gán cho nó một tên logic. Các dự án khác sau đó có thể sử dụng tên này để tìm và giao tiếp với nó, loại bỏ nhu cầu về các URL hoặc số cổng được mã hóa cố định.
  • Quản lý container: Aspire tận dụng thời gian chạy container cục bộ của bạn (như Docker) để tải xuống và chạy các phụ thuộc được containerized mà bạn khai báo, chẳng hạn như Redis hoặc PostgreSQL, đảm bảo chúng luôn khả dụng trong quá trình phát triển.

Bằng cách bọc các dự án hiện có của bạn với lớp điều phối này, Aspire cung cấp một trải nghiệm phát triển nhất quán và có thể lặp lại, có thể quan sát được đầy đủ và đơn giản hóa đường dẫn đến production.

Chỉ mục