PageRenderTime 143ms CodeModel.GetById 81ms app.highlight 3ms RepoModel.GetById 37ms app.codeStats 0ms

/src/LinFu.AOP/Factories/AddInvocationInfoActionFactory.cs

http://github.com/philiplaureano/LinFu
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}