IoC là gì?
IoC là một nguyên lý thiết kế nổi tiếng với mục đích làm giảm sự phụ
thuộc giữa các tầng, các thành phần và các lớp bằng cách nghịch đảo
luồng điểu khiển của ứng dụng.
Trong phương pháp lập trình truyền thống, việc kiểm soát luồng thực hiện
chương trình và các lớp con được thực hiện 1 cách rất chặt chẽ thì IoC
lại tách mã thực thi từ mã vấn đề cụ thể. Cách tiếp cận này cho phép các
thành phần khác nhau được phát triển một cách độc lập.
Ví dụ: trong ứng dụng MVC, lớp model, view và controller được thiết kế và xây dựng độc lập với nhau.
Hai triển khai phổ biến của nguyên lý IoC là Dependency Injection (chống lại sự phụ thuộc) và service location.
Dependency Injection
Dependency Injection (DI) là một design pattern được sử dụng để triển khai IoC. Nó cho phép tạo ra các đối tượng phụ thuộc bên ngoài của một class và cung cấp các đối tượng đó cho class thông qua các cách khác nhau. Sử dụng DI, chúng ta di chuyển việc tạo ra và liên kết các đối tượng phụ thuộc ra khỏi class phụ thuộc vào chúng.
Setup DI cho Azure Functions
Để tạo Project Azure Functions, bạn bấm vào biểu tượng Azure Function ở thanh sidebar bên tráiChọn ngôn ngữ (C#, Typescript...), chọn event cho Function App
Authorize: chọn Function
Chọn Workspace, tên class Project sẽ được tạo như sauĐầu tiên, chúng ta hãy xem xét 1 ví dụ đơn giản. Trong ví dụ này, chúng ta chỉ cho hiện câu Hello World được lấy từ MessageProcessor.
Tạo Class Library, thêm interface IMessageProcessor và class MessageProcessor
namespace DependencyInjectonSample.Core;
public interface IMessageProcessor
{
string Process(string name);
}
public class MessageProcessor : IMessageProcessor
{
public string Process(string name)
{
if (name.Contains("exception"))
throw new Exception("Exception found in message");
return $"Hello {name}";
}
}
Thêm Startup class để hỗ trợ Inject Dependency
Cài đặt packagedotnet add package Microsoft.Azure.Functions.Extension
Thêm class Startup trong project chứa Function Apps
using DependencyInjectonSample.Core;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(DependencyInjectonSample.Startup))]
namespace DependencyInjectonSample;
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddTransient<IMessageProcessor, MessageProcessor>();
builder.Services.AddLogging();
}
}
FunctionsStartup là một attribute dùng để đăng ký một class Startup cho Azure Functions. Class Startup này phải kế thừa từ lớp trừu tượng FunctionsStartup và ghi đè phương thức Configure để cấu hình và thêm các service vào một IFunctionsHostBuilder instance. Azure Functions host sẽ tạo ra một instance của IFunctionsHostBuilder và truyền nó trực tiếp vào phương thức Configure của class Startup
Quay trở lại Function, bạn cập nhật lại như sau:public class DependencyInjectionFunctionApp
{
private readonly ILogger<DependencyInjectionFunctionApp> _logger;
private readonly IMessageProcessor _messageProcessor;
public DependencyInjectionFunctionApp(ILogger<DependencyInjectionFunctionApp> log, IMessageProcessor messageProcessor)
{
_logger = log;
_messageProcessor = messageProcessor;
}
[FunctionName("DependencyInjectionFunctionApp")]
[OpenApiOperation(operationId: "Run", tags: new[] { "name" })]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiParameter(name: "name", In = ParameterLocation.Path, Required = true, Type = typeof(string), Description = "The **Name** parameter")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "text/plain", bodyType: typeof(string), Description = "The OK response")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "Hello/{name}")] HttpRequest req, string name)
{
_logger.LogInformation("C# HTTP trigger function processed a request.");
_logger.LogInformation($"{name}");
var message = _messageProcessor.Process(name);
string responseMessage = $"{message}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}
}
Đọc giá trị Settings trong Azure functions
Chúng ta sẽ sử dụng Option Patterns để đọc giá trị settings và trả settings về dạng strong typeThe options pattern uses classes to provide strongly-typed access to groups of related settings.Giả sử chúng ta thêm Url và Secret vào local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"SiteManager:Url": "https://nhatkyhoctap.blogspot.com",
"SiteManager:Secret": "abc"
}
}
Thêm đoạn code vào trong hàm Configure()
builder.Services.AddOptions<MyConfigOptions>()
.Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("SiteManager").Bind(settings);
});
Gọi Dependency trong constructor
private readonly MyConfigOptions _myConfigOptions;
public DependencyInjectionFunctionApp(ILogger<DependencyInjectionFunctionApp> log, IMessageProcessor messageProcessor, IOptions<MyConfigOptions> configOptions)
{
_logger = log;
_messageProcessor = messageProcessor;
_myConfigOptions = configOptions.Value;
}
Hi vọng với bài viết này, bạn sẽ sử dụng Dependency Injection trong Azure Functions dễ dàng hơn
Happy coding
Nhận xét
Đăng nhận xét