public void TestExtensionMethod() { var p1 = Expression.Parameter(typeof(int)); var p2 = Expression.Parameter(typeof(int)); var lambda = Expression.Lambda <Func <int, int, int> >( Expression.Add(p1, p2), p1, p2); var translator = new ExpressionTranslator(new TypeDefinitions { IsStatic = true, Namespace = "ExpressionDebugger.Tests", TypeName = "MockClass" }); translator.VisitLambda(lambda, ExpressionTranslator.LambdaType.ExtensionMethod, "Add"); var str = translator.ToString(); Assert.AreEqual(@" namespace ExpressionDebugger.Tests { public static partial class MockClass { public static int Add(this int p1, int p2) { return p1 + p2; } } }".Trim(), str); }
private static void GenerateMappers(MapperOptions opt) { using var dynamicContext = new AssemblyResolver(Path.GetFullPath(opt.Assembly)); var assembly = dynamicContext.Assembly; var config = TypeAdapterConfig.GlobalSettings; config.SelfContainedCodeGeneration = true; config.Scan(assembly); foreach (var type in assembly.GetTypes()) { if (!type.IsInterface) { continue; } var attr = type.GetCustomAttribute <MapperAttribute>(); if (attr == null) { continue; } Console.WriteLine($"Processing: {type.FullName}"); var definitions = new TypeDefinitions { Implements = new[] { type }, Namespace = opt.Namespace ?? type.Namespace, TypeName = attr.Name ?? GetImplName(type.Name), IsInternal = attr.IsInternal, PrintFullTypeName = opt.PrintFullTypeName, }; var translator = new ExpressionTranslator(definitions); var interfaces = type.GetAllInterfaces(); foreach (var @interface in interfaces) { foreach (var prop in @interface.GetProperties()) { if (!prop.PropertyType.IsGenericType) { continue; } if (prop.PropertyType.GetGenericTypeDefinition() != typeof(Expression <>)) { continue; } var propArgs = prop.PropertyType.GetGenericArguments()[0]; if (!propArgs.IsGenericType) { continue; } if (propArgs.GetGenericTypeDefinition() != typeof(Func <,>)) { continue; } var funcArgs = propArgs.GetGenericArguments(); var tuple = new TypeTuple(funcArgs[0], funcArgs[1]); var expr = config.CreateMapExpression(tuple, MapType.Projection); translator.VisitLambda(expr, ExpressionTranslator.LambdaType.PublicLambda, prop.Name); } } foreach (var @interface in interfaces) { foreach (var method in @interface.GetMethods()) { if (method.IsGenericMethod) { continue; } if (method.ReturnType == typeof(void)) { continue; } var methodArgs = method.GetParameters(); if (methodArgs.Length < 1 || methodArgs.Length > 2) { continue; } var tuple = new TypeTuple(methodArgs[0].ParameterType, method.ReturnType); var expr = config.CreateMapExpression(tuple, methodArgs.Length == 1 ? MapType.Map : MapType.MapToTarget); translator.VisitLambda(expr, ExpressionTranslator.LambdaType.PublicMethod, method.Name); } } var code = translator.ToString(); var path = Path.Combine(Path.GetFullPath(opt.Output), definitions.TypeName + ".g.cs"); WriteFile(code, path); } }