Chuyển đến nội dung chính

Azure Functions: Sử dụng Dependency Injection - Day 5

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ái

Chọn ngôn ngữ (C#, Typescript...), chọn event cho Function App 


Authorize: chọn Function 

Screenshot for creating function authorization.

Chọn Workspace, tên class Screenshot for selectIng Add to workplace.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 package
dotnet 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 type
The 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

Bài đăng phổ biến từ blog này

[ASP.NET MVC] Authentication và Authorize

Một trong những vấn đề bảo mật cơ bản nhất là đảm bảo những người dùng hợp lệ truy cập vào hệ thống. ASP.NET đưa ra 2 khái niệm: Authentication và Authorize Authentication xác nhận bạn là ai. Ví dụ: Bạn có thể đăng nhập vào hệ thống bằng username và password hoặc bằng ssh. Authorization xác nhận những gì bạn có thể làm. Ví dụ: Bạn được phép truy cập vào website, đăng thông tin lên diễn đàn nhưng bạn không được phép truy cập vào trang mod và admin.

ASP.NET MVC: Cơ bản về Validation

Validation (chứng thực) là một tính năng quan trọng trong ASP.NET MVC và được phát triển trong một thời gian dài. Validation vắng mặt trong phiên bản đầu tiên của asp.net mvc và thật khó để tích hợp 1 framework validation của một bên thứ 3 vì không có khả năng mở rộng. ASP.NET MVC2 đã hỗ trợ framework validation do Microsoft phát triển, tên là Data Annotations. Và trong phiên bản 3, framework validation đã hỗ trợ tốt hơn việc xác thực phía máy khách, và đây là một xu hướng của việc phát triển ứng dụng web ngày nay.

Tổng hợp một số kiến thức lập trình về Amibroker

Giới thiệu về Amibroker Amibroker theo developer Tomasz Janeczko được xây dựng dựa trên ngôn ngữ C. Vì vậy bộ code Amibroker Formula Language sử dụng có syntax khá tương đồng với C, ví dụ như câu lệnh #include để import hay cách gói các object, hàm trong các block {} và kết thúc câu lệnh bằng dấu “;”. AFL trong Amibroker là ngôn ngữ xử lý mảng (an array processing language). Nó hoạt động dựa trên các mảng (các dòng/vector) số liệu, khá giống với cách hoạt động của spreadsheet trên excel.