WeihanLi.Npoi 1.18.0 Released
WeihanLi.Npoi 1.18.0 Released
Intro
前段時間一直在想,把現(xiàn)在的配置做成類似于 AutoMapper 和 FluentValidation 那樣,把每個類型的 mapping 配置放在一個類中,這樣我們就可以比較好地組織我們的 mapping 關(guān)系,也可以配置多個 mapping,動態(tài)地進(jìn)行切換,于是就想著今天實(shí)現(xiàn)這個 feature。
Sample
在 1.18.0 版本中會加入一個 IMappingProfile<TEntity> 的接口,要使用 fluent API 方式自定義 mapping 關(guān)系的時候可以實(shí)現(xiàn)這個接口,這個接口的定義非常的簡單,定義如下:
public?interface?IMappingProfile { }public?interface?IMappingProfile<T> {public?void?Configure(IExcelConfiguration<T>?configuration); }這里增加了一個非泛型的接口,實(shí)際使用主要是使用泛型接口,非泛型的接口目前是一個空接口,用來過濾不符合條件的類型。
使用的示例如下:
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 的類型成員,可以根據(jù)需要自行選擇:
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
實(shí)現(xiàn)方式比較簡單,通過掃描程序集或加載指定類型,通過反射創(chuàng)建一個 mapping profile 實(shí)例并注冊 mapping 關(guān)系。
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
具體使用可以參考項(xiàng)目單元測試和另外一個示例項(xiàng)目:https://github.com/OpenReservation/ReservationServer
利用 Source Generator 我們可以進(jìn)一步的將反射的這一過程進(jìn)行優(yōu)化,在編譯時生成強(qiáng)類型的注冊代碼,這樣也可以進(jìn)一步地優(yōu)化注冊性能,不過考慮實(shí)際注冊的時候一般只會執(zhí)行一次,而且目前 VS、Rider 對 Source Generator 的支持不是特別好,也就暫時沒考慮使用 Source Generator 的方式來做,后面可以再做優(yōu)化
希望能夠通過這樣的功能把 mapping 關(guān)系的配置更好的組織起來,如果使用時有遇到問題或者覺得需要改進(jìn)的,歡迎通過項(xiàng)目 issue 反饋
References
https://github.com/WeihanLi/WeihanLi.Npoi
https://github.com/OpenReservation/ReservationServer
總結(jié)
以上是生活随笔為你收集整理的WeihanLi.Npoi 1.18.0 Released的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过Dapr实现一个简单的基于.net的
- 下一篇: Source Generators(源代