利用dotnet core的代码生成实现类似AutoMapper的类型转换
利用dotnet core的代码生成的特性,自动生成类型转换的代码。类似于AutoMaper,但是代码生成近似于手写代码,不用反射,性能更好
生成通过比较属性名字(不区分大小写)
属性支持简单类型,类,List,Dictionary(key最好是string类型)
在需要转换的类上标记特性:ConvertFrom、ConvertTo
[ConvertTo(typeof(B))] [ConvertFrom(typeof(B))] public partial class A { public int Age { get; set; } public Dictionary<string, A2> Dic { get; set; } } public partial class A2 { public int MyProperty { get; set; } } public class B { public int Age { get; set; } public Dictionary<string,B2> Dic { get; set; } } public class B2 { public int MyProperty { get; set; } }
上面的例子生成如下代码:
public partial class A { public static A ConvertFrom(ConverterTest.B item) { if(item != null) { var r = new ConverterTest.A(); r.Age = item.Age; if(item.Dic != null) r.Dic = item.Dic.ToDictionary(a => a.Key, b => { if(b.Value != null) { var c2 = new ConverterTest.A2(); c2.MyProperty = b.Value.MyProperty; return c2; } else return null; }); return r; } else return null; } public static List<A> ConvertListFrom(IList<ConverterTest.B> items) => items.Select(p => A.ConvertFrom(p)).ToList(); } public partial class A { public ConverterTest.B ConvertToB() { if(this != null) { var r = new ConverterTest.B(); r.Age = this.Age; if(this.Dic != null) r.Dic = this.Dic.ToDictionary(a => a.Key, b => { if(b.Value != null) { var c2 = new ConverterTest.B2(); c2.MyProperty = b.Value.MyProperty; return c2; } else return null; }); return r; } else return null; } public static List<ConverterTest.B> ConvertListTo(IList<ConverterTest.A> items) => items.Select(p => p.ConvertToB()).ToList(); }
实现是很直接的,就是拼接代码。之前的实现是继承ISourceGenerator,后面有了一个IIncrementalGenerator,后者性能更高(利用了缓存),就换了实现
具体实现可以在这里看:https://gitee.com/di-ao/convert-generator
使用:
可通过nuget进行安装,在nuget上搜索:ConvertGenerator
直接安装就可以了。
参考:
Source generator updates: incremental generators (andrewlock.net)
roslyn/docs/features/incremental-generators.md at main · dotnet/roslyn · GitHub
Creating an incremental generator --- 创建增量生成器 (andrewlock.net)
Solving the source generator 'marker attribute' problem - Part 2 (andrewlock.net)