+++ title = "dynamica" draft = false tags = [ "code", "csharp", "dynamica" ] date = "2014-11-05" +++ # Dynamica Zie ook [code/csharp/reflectie]({{< relref "wiki/code/csharp/reflectie.md" >}}) ### Expression trees opbouwen ##### Van een MethodInfo instantie naar een Func<> ```csharp var instanceToMemoize = Activator.CreateInstance(); foreach (var method in instanceToMemoize.GetType().GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) { var parameters ###### method.GetParameters().Select(p > Expression.Constant("test")); var expr = Expression.Lambda(Expression.Call(Expression.Constant(instanceToMemoize), method, parameters)).Compile(); _Delegates.Add(method.ToString(), expr); } ``` Argumenten stuk klopt nog niet. Refs: 1. http://stackoverflow.com/questions/2933221/can-you-get-a-funct-or-similar-from-a-methodinfo-object 2. http://stackoverflow.com/questions/11367830/how-to-find-full-name-of-calling-method-c-sharp ##### Memoization Ook mogelijk via `Func<>` wrappers; zie 1. http://www.jaylee.org/post/2013/04/18/Memoization-and-Immutable-data-in-CSharp-Part-1.aspx 2. http://www.jaylee.org/post/2013/04/22/Immutable-Data-and-Memoization-in-CSharp-Part-2.aspx Dit is een extension die 2 type arguments aanvaard: ```csharp public static Func AsMemoized(this Func func) { var values = new Dictionary, TResult>(); return (arg1, arg2) => MemoizedValue(func, arg1, arg2, values); } public static Func AsMemoized(this Func funcArg) { Func func ###### (arg1, arg2) > funcArg(arg1); var values = new Dictionary, TResult>(); return (arg) => MemoizedValue(func, arg, null, values); } private static TResult MemoizedValue(Func func, TArg1 arg1, TArg2 arg2, Dictionary, TResult> values) { TResult value; var memoizedKey = new MemoizedKey(arg1, arg2); if (!values.TryGetValue(memoizedKey, out value)) { value ###### values[memoizedKey] func(memoizedKey.Arg1, memoizedKey.Arg2); } return value; } private class MemoizedKey { public MemoizedKey(TArg1 arg1, TArg2 arg2) { Arg1 = arg1; Arg2 = arg2; } public TArg1 Arg1 { get; private set; } public TArg2 Arg2 { get; private set; } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; return Equals((MemoizedKey)obj); } public override int GetHashCode() { unchecked { return (EqualityComparer.Default.GetHashCode(Arg1) * 397) ^ EqualityComparer.Default.GetHashCode(Arg2); } } private bool Equals(MemoizedKey other) { return EqualityComparer.Default.Equals(Arg1, other.Arg1) && EqualityComparer.Default.Equals(Arg2, other.Arg2); } } ``` Equals is nodig voor de `Dictionary` (generated). ### Aspect Oriented Programming **PostSharp**: [http:*www.postsharp.net](http:*www.postsharp.net) #### Transacties wiren Zie [code/csharp/persistence]({{< relref "wiki/code/csharp/persistence.md" >}}) #### Aspects applyen op assembly level Q: Ik wil AOP toepassen voor alle klassen (& [publieke] methods) in een bepaald project (DLL)

A: Gebruik [Multicasting aspects](http://www.postsharp.net/aspects/multicasting). Bijvoorbeeld, om exceptions overal op te vangen, en dan door te delegeren, evt screenshot van de app te nemen: ```csharp [assembly: ScenarioTests.ScenarioExceptionHandler] namespace ScenarioTests { [Serializable] [ScenarioExceptionHandler(AttributeExclude = true)] public class ScenarioExceptionHandler : OnMethodBoundaryAspect { public override void OnException(MethodExecutionArgs args) { WebDriverExceptionHandler.Handle(args.Exception); base.OnException(args); } } } ``` De eerste regel, `[assembly:]` is van belang, zie documentatie. Je kan ook verder filteren by visibility etc, zoals in [Spring AOP/AspectJ]({{< relref "wiki/code/java/dynamica/aspectj.md" >}}) de strings in XML gedfiniƫerd zijn.