Metaprogramming in .NET

52
Metaprogramming in .NET Jason Bock Practice Lead

Transcript of Metaprogramming in .NET

Metaprogramming in .NET

Jason BockPractice Lead

»http://www.magenic.com

»http://www.jasonbock.net

»https://www.twitter.com/jasonbock

»https://www.github.com/jasonbock

» [email protected]

Personal Info

https://github.com/JasonBock

Downloads

»Definitions

»Reflection

»Snippets

»Expressions

»Modification

»Compilation

Overview

Remember…

https://github.com/JasonBock

Definitions

http://kauilapele.files.wordpress.com/2011/11/magic.gif

Definitions

http://en.wikipedia.org/wiki/Metaprogramming

Metaprogramming: The writing of computer programs that write or

manipulate other programs (or themselves) as their data, or that do part of the work at compile time that would otherwise be done at runtime.

Definitions

http://manning.com/hazzard/

Definitions

http://manning.com/hazzard/

“The meta prefix can mean changedor higher. It can also mean after or

beside, depending on the context. All of those terms describe … various

forms of metaprogramming.”

Definitions

http://1.bp.blogspot.com/-MoYos-iLGR0/Tclyxk6kH6I/AAAAAAAAF08/8aX2fOxBKlo/s1600/magical-merlin-sundara-

fawn.jpg

dynamic x = Program.Create();x.MyProperty = 42;x.Calculate();

Definitions

http://1.bp.blogspot.com/-MoYos-iLGR0/Tclyxk6kH6I/AAAAAAAAF08/8aX2fOxBKlo/s1600/magical-merlin-sundara-

fawn.jpg

var x = 40;eval('x = x + 2');

Definitions

http://www.wired.com/images_blogs/photos/uncategorized/2008/04/15/complexity.jpg

Definitions

http://www.machinemart.co.uk/images/library/range/large/1010.jpg

Definitions

http://www.machinemart.co.uk/images/library/range/large/1010.jpg

…if you’ve come this far, maybe you’rewilling to come a little further.

Reflection

http://scarlettlibrarian.files.wordpress.com/2010/12/reflection.jpg

Reflection

[TestClass]public class MyTests{

[TestMethod]public void MyTest() { }

[TestMethod]public void AnotherTest() { }

}

Find test classes

MyTests

Find test methods

MyTest

AnotherTest

Reflection

public class AClass {}public class AnotherClass {}public class MyClass{public void MyMethod(string arg1,

Guid arg2) { ... }}

Reflection

Assembly

TypeTypeType

MethodBase

ParameterInfoParameterInfo

Reflection

MyAssembly

AnotherClassMyClassAClass

MyMethod

arg2arg1

Reflection

var arg2Type = typeof(MyClass).GetMethod("MyMethod").GetParameters()[1].ParameterType;

Reflection

var mine = new MyClass();var invoke = typeof(MyClass).GetMethod("MyMethod").Invoke(mine, new object[]

{ "data", Guid.NewGuid() });

Reflection

http://www.theawall.com/images/blog/time.jpg

Demo: Automatically Adding Business RulesMetaprogramming in .NET

Snippets

http://osx.wdfiles.com/local--files/icon:snippet/Snippet.png

Snippets

Snippets

Demo: ArgumentNullException Code SnippetMetaprogramming in .NET

Expressions

Expressions

Expressions

public sealed class NotNullAttribute : InjectorAttribute<ParameterDefinition>{}

Expressions»System.Reflection.Emit

»DynamicMethod

Expressions

http://www.theawall.com/images/blog/time.jpg

Expressions

public string SayHello(){return "Hello";

}

Expressions

.method public hidebysig instance string SayHello() cil managed

{.maxstack 8ldstr "Hello"ret

}

Expressions

.method public hidebysig instance string SayHello() cil managed

{.maxstack 8ret

}

Expressions

*

3 x

/

2

+

4

f(x) = ((3 * x) / 2) + 4

Expressionsvar method = new DynamicMethod("m",

typeof(double), new Type[] { typeof(double) });var parameter = method.DefineParameter(

1, ParameterAttributes.In, "x");var generator = method.GetILGenerator();generator.Emit(OpCodes.Ldc_R8, 3d);generator.Emit(OpCodes.Ldarg_0);generator.Emit(OpCodes.Mul);generator.Emit(OpCodes.Ldc_R8, 2d);generator.Emit(OpCodes.Div);generator.Emit(OpCodes.Ldc_R8, 4d);generator.Emit(OpCodes.Add);generator.Emit(OpCodes.Ret);var compiledMethod = method.CreateDelegate(

typeof(Func<double, double>)) as Func<double, double>;

Expressionsvar parameter =

Expression.Parameter(typeof(double));var method = Expression.Lambda(

Expression.Add(Expression.Divide(

Expression.Multiply(Expression.Constant(3d), parameter),

Expression.Constant(2d)),Expression.Constant(4d)),

parameter).Compile() as Func<double, double>;

Expressions

var propertyName = this.GetPropertyName(_ => _.FirstName);

// Or, in C#6...// var propertyName = // nameof(this.FirstName);

Demo: Evolving CodeMetaprogramming in .NET

Modification

[MaximumCalls(2)]public void MyMethod { }

Modification

private int myMethodCalls;

[MaximumCalls(2)]public void MyMethod{ if(this.myMethodCalls < 2) {

//...this.myMethodCalls++;

}}

Demo: InjectorsMetaprogramming in .NET

Compilation

Compilation

Syntax Tree API

Symbol API Binding and Flow API Emit API

https://github.com/dotnet/roslyn

Compilation

ITest

CallMe()

var rock = new Rock<ITest>;rock.HandleAction<int>(_ => _.CallMe(),() => { return 42; });

var chunk = rock.Make();chunk.CallMe();

Rock841914: ITest

Compilation

http://phillbarron.files.wordpress.com/2012/01/confused.jpg

Compilation

Demo: RocksMetaprogramming in .NET

Summary»What didn’t I cover?

› CodeDom

› T4

› Reflection.Emit

› CCI (like Cecil) (http://ccimetadata.codeplex.com/)

› dynamic, ExpandoObject

› Clay (http://clay.codeplex.com/), Gemini (http://amirrajan.net/Oak/)

Summary

http://upload.wikimedia.org/wikipedia/commons/d/de/CERO_fear.png

Summary

http://upload.wikimedia.org/wikipedia/commons/d/de/CERO_fear.png

Metaprogramming in .NET

Jason BockPractice Lead

Remember… https://github.com/JasonBock (see notes for specific repos) http://www.slideshare.net/jasonbock/metaprogramming-in-net References in the notes on this slide