如何在LinqPad 7的C#(.NET Core/5/6)环境中使用Metalama的OverrideMethodAspect实现方法参数日志记录
OverrideMethodAspect in LINQPad Yep, you're right—Metalama's aspect-oriented programming relies on its build-time code weaving, which hooks into Visual Studio's build pipeline by default. Since LINQPad uses plain Roslyn compilation without that integration, the aspects won't apply automatically. But there's a way to make this work by manually invoking Metalama's compiler in your LINQPad query. Here's how:
Step 1: Add Metalama to LINQPad
First, fire up LINQPad's NuGet manager, search for Metalama.Framework, and install it—make sure you check the "Include prereleases" box, since Metalama's newer features are often in pre-release builds.
Step 2: Use Metalama's Compiler API to Weave Aspects
LINQPad lets us take control of the compilation process. We'll use Metalama's MetalamaCompiler class to explicitly apply aspect weaving before executing the code. Here's a complete working example for your SimpleLog aspect:
// Reference Metalama assemblies (added via NuGet) #r "Metalama.Framework.dll" #r "Metalama.Framework.Compiler.dll" using Metalama.Framework.Aspects; using Metalama.Framework.Compiler; using System; using System.Linq; // Define your aspect exactly as you would in Visual Studio public class SimpleLogAttribute : OverrideMethodAspect { public override dynamic OverrideMethod() { Console.WriteLine($"Entering Method - first arg value is: {meta.Target.Method.Parameters.First().Value}"); try { return meta.Proceed(); } finally { Console.WriteLine($"Leaving {meta.Target.Method}"); } } } // Use Metalama to compile our code with aspects applied var metalamaCompiler = MetalamaCompiler.CreateDefault(); // Compile the source code that uses the aspect var compiledAssembly = metalamaCompiler.Compile( sourceCode: @" using System; public class Program { [SimpleLog] public static void TestMethod(string x) { Console.WriteLine(""Hello, "" + x); } }", references: AppDomain.CurrentDomain.GetAssemblies() .Where(a => !a.IsDynamic && !string.IsNullOrEmpty(a.Location)) .Select(a => a.Location) // Include the assembly where our SimpleLogAttribute is defined .Append(typeof(SimpleLogAttribute).Assembly.Location) ); // Execute the woven method var programType = compiledAssembly.GetType("Program"); var testMethod = programType.GetMethod("TestMethod"); testMethod.Invoke(null, new object[] { "foo" });
What's Happening Here?
- We're using
MetalamaCompilerto handle the aspect weaving that Visual Studio normally does automatically. This processes the[SimpleLog]attribute and generates the modified code with the logging logic injected. - We include all necessary assembly references, including the one where our custom aspect lives, to ensure the compilation succeeds.
- After compiling, we load the generated assembly and invoke the
TestMethodmethod dynamically—you'll see the logging output just like you would in Visual Studio.
For reference, here's the original code that works in Visual Studio:
using Metalama.Framework.Aspects; public class Program { public static void Main(string[] args) { TestMethod("foo"); } [SimpleLog] public static void TestMethod(string x) { Console.WriteLine("Hello, " + x); } } public class SimpleLogAttribute : OverrideMethodAspect { public override dynamic OverrideMethod() { Console.WriteLine($"Entering Method - first arg value is: {meta.Target.Method.Parameters.First().Value}"); try { return meta.Proceed(); } finally { Console.WriteLine($"Leaving {meta.Target.Method}"); } } }
内容的提问来源于stack exchange,提问作者Ambrose Leung

