利用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)

posted @ 2023-06-13 15:38  a14907  阅读(29)  评论(0编辑  收藏  举报