WeihanLi.Npoi 1.18.0 Released

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WeihanLi.Npoi 1.18.0 Released相关的知识,希望对你有一定的参考价值。

WeihanLi.Npoi 1.18.0 Released

Intro

前段时间一直在想,把现在的配置做成类似于 AutoMapperFluentValidation 那样,把每个类型的 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的主要内容,如果未能解决你的问题,请参考以下文章

WeihanLi.Npoi 1.7.0 更新

使用 WeihanLi.Npoi 操作 CSV

WeihanLi.Npoi 1.20.0 Released

WeihanLi.Npoi 近期更新

WeihanLi.Npoi 支持 ShadowProperty 了

WeihanLi.Npoi 根据模板导出Excel