WeihanLi.Npoi 1.18.0 Released
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WeihanLi.Npoi 1.18.0 Released相关的知识,希望对你有一定的参考价值。
WeihanLi.Npoi 1.18.0 Released
Intro
前段时间一直在想,把现在的配置做成类似于 AutoMapper
和 FluentValidation
那样,把每个类型的 mapping 配置放在一个类中,这样我们就可以比较好地组织我们的 mapping 关系,也可以配置多个 mapping,动态地进行切换,于是就想着今天实现这个 feature。
Sample
在 1.18.0 版本中会加入一个 IMappingProfile<TEntity>
的接口,要使用 fluent API 方式自定义 mapping 关系的时候可以实现这个接口,这个接口的定义非常的简单,定义如下:
public interface IMappingProfile
{
}
public interface IMappingProfile<T>
{
public void Configure(IExcelConfiguration<T> configuration);
}
这里增加了一个非泛型的接口,实际使用主要是使用泛型接口,非泛型的接口目前是一个空接口,用来过滤不符合条件的类型。
使用的示例如下:
public class NoticeProfile: IMappingProfile<Notice>
{
public void Configure(IExcelConfiguration<Notice> noticeSetting)
{
noticeSetting
.HasAuthor("WeihanLi")
.HasTitle("WeihanLi.Npoi test")
.HasSheetSetting(setting =>
{
setting.SheetName = "NoticeList";
setting.AutoColumnWidthEnabled = true;
})
;
noticeSetting.Property(_ => _.Id)
.HasColumnIndex(0);
noticeSetting.Property(_ => _.Title)
.HasColumnIndex(1);
noticeSetting.Property(_ => _.Content)
.HasColumnIndex(2);
noticeSetting.Property(_ => _.Publisher)
.HasColumnIndex(3);
noticeSetting.Property(_ => _.PublishedAt)
.HasColumnIndex(4)
.HasColumnOutputFormatter(x => x.ToStandardTimeString());
}
}
在注册 IMappingProfile
的时候我们可以通过指定 Type 和程序集扫描两种方式来注册,Type 注册可以获取类型的可访问性,只要能够编译通过就能注册成功,程序集扫描只扫描 public
的类型成员,可以根据需要自行选择:
void LoadMappingProfiles(params Assembly[] assemblies);
void LoadMappingProfiles(params Type[] types);
使用示例如下:
// Load by type
FluentSettings.LoadMappingProfiles(typeof(NoticeProfile));
// Load by assembly
FluentSettings.LoadMappingProfiles(typeof(NoticeProfile).Assembly);
What's Inside
实现方式比较简单,通过扫描程序集或加载指定类型,通过反射创建一个 mapping profile 实例并注册 mapping 关系。
foreach (var type in types.Where(x => x.IsAssignableTo<IMappingProfile>()))
{
var profileInterfaceType = type.GetImplementedInterfaces()
.FirstOrDefault(
x => x.IsGenericType && x.GetGenericTypeDefinition() == s_profileGenericTypeDefinition);
if (profileInterfaceType is null)
{
continue;
}
var profile = Activator.CreateInstance(type);
var entityType = profileInterfaceType.GetGenericArguments()[0];
var configuration = InternalHelper.GetExcelConfigurationMapping(entityType);
var method = profileInterfaceType.GetMethod(MappingProfileConfigureMethodName,
new[] {typeof(IExcelConfiguration<>).MakeGenericType(entityType)});
method?.Invoke(profile, new object[] {configuration});
}
More
具体使用可以参考项目单元测试和另外一个示例项目:https://github.com/OpenReservation/ReservationServer
利用 Source Generator 我们可以进一步的将反射的这一过程进行优化,在编译时生成强类型的注册代码,这样也可以进一步地优化注册性能,不过考虑实际注册的时候一般只会执行一次,而且目前 VS、Rider 对 Source Generator 的支持不是特别好,也就暂时没考虑使用 Source Generator 的方式来做,后面可以再做优化
希望能够通过这样的功能把 mapping 关系的配置更好的组织起来,如果使用时有遇到问题或者觉得需要改进的,欢迎通过项目 issue 反馈
References
https://github.com/WeihanLi/WeihanLi.Npoi
https://github.com/OpenReservation/ReservationServer
以上是关于WeihanLi.Npoi 1.18.0 Released的主要内容,如果未能解决你的问题,请参考以下文章