上一篇有一個讀者,有疑問,如何自動化注冊Dto
我開篇,做了一個自動化注冊的
public sealed class AutoInjectAttribute : Attribute { public Type SourceType { get; } public Type TargetType { get; } public AutoInjectAttribute(Type sourceType, Type targetType) { SourceType = sourceType; TargetType = targetType; } }
增加了一個特性,在Dto上面打上,參數1是源類型,參數2是Dto類型
增加一個工廠類保存自動轉換的類型
public class AutoInjectFactory { public List<(Type,Type)> ConvertList { get; } = new List<(Type, Type)>(); public void AddAssemblys(params Assembly[] assemblys) { foreach (var assembly in assemblys) { var atributes = assembly.GetTypes() .Where(_type => _type.GetCustomAttribute<AutoInjectAttribute>() != null) .Select(_type => _type.GetCustomAttribute<AutoInjectAttribute>()); foreach (var atribute in atributes) { ConvertList.Add((atribute.SourceType, atribute.TargetType)); } } } }
在原來的AddAutoMapper上找到修改的代碼段
public static IServiceCollection AddAutoMapper(this IServiceCollection service) { ...略 service.TryAddSingleton(serviceProvider => { var mapperConfigurationExpression = serviceProvider.GetRequiredService<MapperConfigurationExpression>(); var instance = new MapperConfiguration(mapperConfigurationExpression); instance.AssertConfigurationIsValid(); return instance; }); ...略 return service; }
改為
public static IServiceCollection AddAutoMapper(this IServiceCollection service) { ...略 service.TryAddSingleton(serviceProvider => { var mapperConfigurationExpression = serviceProvider.GetRequiredService<MapperConfigurationExpression>(); var factory = serviceProvider.GetRequiredService<AutoInjectFactory>(); foreach (var (sourceType,targetType) in factory.ConvertList) { mapperConfigurationExpression.CreateMap(sourceType, targetType); } var instance = new MapperConfiguration(mapperConfigurationExpression); instance.AssertConfigurationIsValid(); return instance; }); ...略 return service; }
增加一組擴展方法
public static class AutoMapperExtension { ...略 public static void UseAutoInject(this IApplicationBuilder applicationBuilder, params Assembly[] assemblys) { var factory = applicationBuilder.ApplicationServices.GetRequiredService<AutoInjectFactory>(); factory.AddAssemblys(assemblys); } }
在Startup.Configure方法內調用一下
看看測試
增加一個測試控制器
執行結果