/src/LinFu.AOP/Factories/AddInvocationInfoActionFactory.cs
C# | 57 lines | 35 code | 6 blank | 16 comment | 2 complexity | a7f7dc90d1de3298549e8a3591a81768 MD5 | raw file
1using System; 2using System.Linq; 3using LinFu.AOP.Cecil.Interfaces; 4using LinFu.AOP.Interfaces; 5using LinFu.IoC.Configuration; 6using LinFu.IoC.Interfaces; 7using LinFu.Reflection.Emit; 8using Mono.Cecil; 9using Mono.Cecil.Cil; 10 11namespace LinFu.AOP.Cecil.Factories 12{ 13 /// <summary> 14 /// A factory instance that creates <see cref="Action{T}" /> delegates 15 /// that emit the necessary <see cref="IInvocationInfo" /> information 16 /// and store it in a local variable named '__invocationInfo___'. 17 /// </summary> 18 [Factory(typeof(Action<MethodDefinition>), ServiceName = "AddInvocationInfo")] 19 public class AddInvocationInfoActionFactory : IFactory 20 { 21 /// <summary> 22 /// Generates the <see cref="Action{T}" /> delegate that will emit 23 /// the necessary <see cref="IInvocationInfo" /> information. 24 /// </summary> 25 /// <param name="request">The <see cref="IFactoryRequest" /> instance that describes the requested service type.</param> 26 /// <returns> 27 /// A delegate that can emit the necessary <see cref="IInvocationInfo" /> context that will allow other developers 28 /// to infer information about the method currently being executed. 29 /// </returns> 30 public object CreateInstance(IFactoryRequest request) 31 { 32 var container = request.Container; 33 Action<MethodDefinition> result = 34 method => 35 { 36 var body = method.Body; 37 38 // Add the IInvocationInfo 39 // instance only once 40 var localAlreadyExists = (from VariableDefinition local in body.Variables 41 where local.Name == "___invocationInfo___" 42 select local).Count() > 0; 43 44 if (localAlreadyExists) 45 return; 46 47 var variable = method.AddLocal<IInvocationInfo>(); 48 variable.Name = "___invocationInfo___"; 49 50 var emitInfo = (IEmitInvocationInfo) container.GetService(typeof(IEmitInvocationInfo)); 51 emitInfo.Emit(method, method, variable); 52 }; 53 54 return result; 55 } 56 } 57}