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.
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.
Ở Project Services, bạn khai báo:
Đ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
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!
Cài đặt Autofac
Cài đặt packages từ Nuget:- Autofac
- Autofac.Extensions.DependencyInjection
// 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
containerBuilder.RegisterModule<DefaultModule>();
Ở đây tiếp tục xuất hiện 2 vấn đề:
- Đ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.
- Bạn khai báo thêm project mới, mà chỉ đăng ký bên Host, quên đăng ký bên DemoHost.
Đ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.zipTham khảo
Dependency injection in a modular architecture like Sitecore Helix: https://thomasddn.blogspot.com/2016/10/dependency-injection-in-modular.htmlModular 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
Đăng nhận xét