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

Sử dụng Autofac Module trong .NET Core

Trong bài viết này, mình sẽ hướng dẫn các bạn sử dụng Autofac trong .NET Core và cách khai báo module DI trong class library.

Cài đặt Autofac

Cài đặt packages từ Nuget:
  • Autofac
  • Autofac.Extensions.DependencyInjection
Hàm ConfigureServices ban đầu:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
 services.AddMvc();
}

Khi sử dụng third-party DI container như Autofac (hoặc Structure-Map), bạn phải thay đổi hàm ConfigureServices, thay vì trả về void, bạn phải trả về IServiceProvider.
public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    // Add other framework services

    // Add Autofac
    var containerBuilder = new ContainerBuilder();
    containerBuilder.RegisterType<MessageRepository>().As<IMessageRepository>();           
    containerBuilder.Populate(services);
    var container = containerBuilder.Build();
    return new AutofacServiceProvider(container);
}
MessageRepository:
public interface IMessageRepository
{
 /// <summary>
 /// return message
 /// </summary>
 /// <returns></returns>
 string GetMessage();
}
public class MessageRepository: IMessageRepository
{
 public string GetMessage()
 {
  return "Message Repository";
 }
}

Sử dụng Autofac Module

Module là một class nhỏ dùng để tập hợp các thành phần có liên quan với nhau, để đơn giản cấu hình và triển khai. Lợi ích của việc đăng ký theo Module là bạn sẽ dễ quản lý các thư viện phụ thuộc, và quan trọng hơn bạn tránh lặp lại code đăng ký Dependency khi sử dụng nhiều web host trỏ vào các service. Đăng ký Module
Ở Project Services, bạn khai báo:
public class DefaultModule : Module
{
 protected override void Load(ContainerBuilder builder)
 {
  builder.RegisterType<MessageRepository>().As<IMessageRepository>();
 }
}
Trong file Startup.cs, bạn cập nhật hàm ConfigureServices:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
 services.AddMvc();
 // Add other framework services

 // Add Autofac
 var containerBuilder = new ContainerBuilder();
 containerBuilder.RegisterModule<DefaultModule>();
 //containerBuilder.RegisterType<MessageRepository>().As<IMessageRepository>();
 containerBuilder.Populate(services);
 var container = containerBuilder.Build();
 return new AutofacServiceProvider(container);
}

Module class đăng ký Dependency Injection

Vấn đề: Giả sử bạn có 1 solution với 3 Projects
  • Module.Core: 1 class Library chứa các logic cơ bản của dự án
  • Module.Host: chứa các khai báo về Controller, Views,...; tham chiếu tới Module.Core
  • Module.DemoHost: chứa các khai báo khác để demo dự án, tham chiếu tới Module.Core
Bạn có thể dễ dang đăng ký Module như hướng dẫn ở trên:
containerBuilder.RegisterModule<DefaultModule>();
Ở đây tiếp tục xuất hiện 2 vấn đề:
  1. Đoạn khai báo Module sẽ lặp lại 2 lần ở 2 file Startup của project Module.Host và project Module.DemoHost. Vi phạm nguyên tắc DRY.
  2. Bạn khai báo thêm project mới, mà chỉ đăng ký bên Host, quên đăng ký bên DemoHost.
Hãy để tất cả tự động đăng ký.
Đoạn code dưới đây nhằm mục đích minh họa cách đọc dll, và đăng ký DI trong Autofac. Trong thực tế, bạn phải đặt tên các Module logic cho tốt, để nhằm phân biệt với Module Host, Module Test, nhằm để gọi dll thật chính xác.
Gợi ý: Bạn có thể dụng Regex Pattern để lọc dll cho từng project.
Khai báo IAutofacDiInitialize

public interface IAutofacDiInitializer
{
 ContainerBuilder Register(ContainerBuilder builder);
}
Khai báo thư viện muốn sử dụng:

public class ServiceModuleInitializer : IAutofacDiInitializer
{
 public virtual ContainerBuilder Register(ContainerBuilder builder)
 {
  builder.RegisterType<MessageRepository>().As<IMessageRepository>().InstancePerLifetimeScope();
  return builder;
 }
}
Khai báo class AutofacConfiguration: Mục đích là để đọc tất cả DLL tương ứng

public class AutofacConfiguration
{
 public static List<IAutofacDiInitializer> GetModuleInitializers()
 {
  var binFolder = new DirectoryInfo(AppContext.BaseDirectory);            
  var assemblyFilenames = binFolder.GetFileSystemInfos().Where(x => x.Name.Contains(".dll"));
  var moduleInitializerType = typeof(IAutofacDiInitializer);
  var result = new List<IAutofacDiInitializer>();
  foreach (var assemblyFileName in assemblyFilenames)
  {
   var assembly = Assembly.Load(new AssemblyName(Path.GetFileNameWithoutExtension(assemblyFileName.Name)));
   var initializerTypes = assembly.GetTypes().Where(x => moduleInitializerType.IsAssignableFrom(x) && x != moduleInitializerType).ToList();
   foreach (var initializerType in initializerTypes)
   {
    if (initializerType != null)
    {
     result.Add(Activator.CreateInstance(initializerType) as IAutofacDiInitializer);
    }
   }
       
  }
  return result;
 }
}
Cập nhật hàm Configure() trong link Startup:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
 services.AddMvc();
 // Add other framework services

 // Add Autofac
 var containerBuilder = new ContainerBuilder();
 var modules = AutofacConfiguration.GetModuleInitializers();
 foreach (var module in modules)
 {
  module.Register(containerBuilder);
 }
 //containerBuilder.RegisterModule<DefaultModule>();
 //containerBuilder.RegisterType<MessageRepository>().As<IMessageRepository>();
 containerBuilder.Populate(services);
 var container = containerBuilder.Build();
 return new AutofacServiceProvider(container);
}
 Download code: http://www.mediafire.com/file/1d2zk9f3rmld6m7/ModularDependencyInjection-autofac-module-dll.zip

Tham khảo

Dependency injection in a modular architecture like Sitecore Helix: https://thomasddn.blogspot.com/2016/10/dependency-injection-in-modular.html
Modular Web Application with ASP.NET Core: https://www.codeproject.com/Articles/1109475/Modular-Web-Application-with-ASP-NET-Core
Chúc các bạn thành công!
Nhatkyhoctap's blog

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.