public void Replace(IMethodContext context, ModuleDefinition targetModule)
        {
            var currentMethod = context.CurrentMethod;
            var currentArguments = context.CurrentArguments;
            var currentArgument = context.CurrentArgument;
            var pushMethod = targetModule.ImportMethod<Stack<object>>("Push");
            var worker = context.CilWorker;

            var methodMap = _context.MethodMap;
            var targetDependency = _context.TargetDependency;
            var interfaceType = _context.InterfaceType;

            var adapterConstructor = _adapterBuilder.CreateAdapterConstructor(methodMap);
            foreach (ParameterReference param in currentMethod.Parameters)
            {
                var arguments = new ParameterContext(worker,
                interfaceType,
                pushMethod,
                currentArguments,
                currentArgument,
                targetDependency, adapterConstructor, param);

                // Save the current argument
                _pushParameter.Adapt(arguments);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Emits a call that obtains the hash code for the current service instance.
        /// </summary>
        /// <param name="il">The <see cref="ILProcessor"/> that points to the method body.</param>
        /// <param name="module">The target module.</param>
        /// <param name="serviceInstance">The local variable that contains the service instance.</param>
        private void GetServiceHash(ILProcessor il, ModuleDefinition module, VariableDefinition serviceInstance)
        {
            il.Emit(OpCodes.Ldloc, serviceInstance);

            var getHashCodeMethod = module.ImportMethod<object>("GetHashCode");
            il.Emit(OpCodes.Callvirt, getHashCodeMethod);
        }
Esempio n. 3
0
        /// <summary>
        /// Emits the instructions that call <see cref="IInitialize.Initialize"/> on a given service instance.
        /// </summary>
        /// <param name="il"></param>
        /// <param name="module">The host module.</param>
        /// <param name="serviceInstance">The local variable that points to the current service instance.</param>
        public void Initialize(ILProcessor il, ModuleDefinition module, VariableDefinition serviceInstance)
        {
            var body = il.Body;
            var method = body.Method;
            var declaringType = method.DeclaringType;

            var targetField = GetTargetField(declaringType);
            if (targetField == null)
                return;

            var initializeType = module.ImportType<IInitialize>();

            il.Emit(OpCodes.Ldloc, serviceInstance);
            il.Emit(OpCodes.Isinst, initializeType);

            var initializeMethod = module.ImportMethod<IInitialize>("Initialize");
            var skipInitializationCall = il.Create(OpCodes.Nop);
            il.Emit(OpCodes.Brfalse, skipInitializationCall);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, targetField);
            GetServiceHash(il, module, serviceInstance);

            var containsMethod = module.ImportMethod<Dictionary<int, int>>("ContainsKey");
            il.Emit(OpCodes.Callvirt, containsMethod);
            il.Emit(OpCodes.Brtrue, skipInitializationCall);

            // if (!__initializedServices.ContainsKey(currentService.GetHashCode()) {
            il.Emit(OpCodes.Ldloc, serviceInstance);
            il.Emit(OpCodes.Isinst, initializeType);
            il.Emit(OpCodes.Ldarg_0);

            il.Emit(OpCodes.Callvirt, initializeMethod);

            // __initializedServices.Add(hashCode, 0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, targetField);
            GetServiceHash(il, module, serviceInstance);
            il.Emit(OpCodes.Ldc_I4_1);

            var addMethod = module.ImportMethod<Dictionary<int, int>>("Add");
            il.Emit(OpCodes.Callvirt, addMethod);

            il.Append(skipInitializationCall);
        }
Esempio n. 4
0
        /// <summary>
        /// Emits the instructions that will obtain the <see cref="IMicroContainer"/> instance.
        /// </summary>
        /// <param name="module">The target module.</param>
        /// <param name="microContainerType">The type reference that points to the <see cref="IMicroContainer"/> type.</param>
        /// <param name="worker">The <see cref="CilWorker"/> that points to the <see cref="IMicroContainer.GetInstance"/> method body.</param>
        /// <param name="skipCreate">The skip label that will be used if the service cannot be instantiated.</param>
        protected override void EmitGetContainerInstance(ModuleDefinition module, TypeReference microContainerType, ILProcessor il, Instruction skipCreate)
        {
            var getNextContainer = module.ImportMethod<IMicroContainer>("get_NextContainer");
            EmitGetNextContainerCall(il, microContainerType, getNextContainer);
            il.Emit(OpCodes.Brfalse, skipCreate);

            // var result = NextContainer.GeService(serviceType, serviceName);
            EmitGetNextContainerCall(il, microContainerType, getNextContainer);
        }
Esempio n. 5
0
 public void Replace(IMethodContext context, ModuleDefinition targetModule)
 {
     var currentMethod = context.CurrentMethod;
     var currentArguments = context.CurrentArguments;
     var popMethod = targetModule.ImportMethod<Stack<object>>("Pop");
     var IL = context.CilWorker;
     foreach (ParameterReference param in currentMethod.Parameters)
     {
         IL.Emit(OpCodes.Ldloc, currentArguments);
         IL.Emit(OpCodes.Callvirt, popMethod);
         IL.Emit(OpCodes.Unbox_Any, param.ParameterType);
     }
 }
        private static void DefineSerializationConstructor(ModuleDefinition module, TypeDefinition targetType)
        {
            var getTypeFromHandle = module.ImportMethod<Type>("GetTypeFromHandle",
                BindingFlags.Public | BindingFlags.Static);

            var parameterTypes = new[] {typeof (SerializationInfo), typeof (StreamingContext)};

            // Define the constructor signature
            var serializationCtor = targetType.AddDefaultConstructor();
            serializationCtor.AddParameters(parameterTypes);

            serializationCtor.Attributes = MethodAttributes.HideBySig | MethodAttributes.SpecialName |
                                           MethodAttributes.RTSpecialName | MethodAttributes.Public;
            var interceptorInterfaceType = module.ImportType<IInterceptor>();
            var interceptorTypeVariable = serializationCtor.AddLocal<Type>();

            var body = serializationCtor.Body;
            body.InitLocals = true;

            var IL = serializationCtor.GetILGenerator();

            IL.Emit(OpCodes.Ldtoken, interceptorInterfaceType);
            IL.Emit(OpCodes.Call, getTypeFromHandle);
            IL.Emit(OpCodes.Stloc, interceptorTypeVariable);

            var defaultConstructor = module.ImportConstructor<object>();
            IL.Emit(OpCodes.Ldarg_0);
            IL.Emit(OpCodes.Call, defaultConstructor);

            // __interceptor = (IInterceptor)info.GetValue("__interceptor", typeof(IInterceptor));
            var getValue = module.ImportMethod<SerializationInfo>("GetValue");
            IL.Emit(OpCodes.Ldarg_0);
            IL.Emit(OpCodes.Ldarg_1);
            IL.Emit(OpCodes.Ldstr, "__interceptor");
            IL.Emit(OpCodes.Ldloc, interceptorTypeVariable);
            IL.Emit(OpCodes.Callvirt, getValue);
            IL.Emit(OpCodes.Castclass, interceptorInterfaceType);

            var setInterceptor = module.ImportMethod<IProxy>("set_Interceptor");
            IL.Emit(OpCodes.Callvirt, setInterceptor);
            ;
            IL.Emit(OpCodes.Ret);
        }
        private static void Emit(CilWorker IL, ModuleDefinition module,
                                 VariableDefinition surroundingImplementation,
                                 VariableDefinition invocationInfo,
                                 VariableDefinition returnValue)
        {
            Instruction skipInvoke = IL.Create(OpCodes.Nop);

            Instruction skipPrint = IL.Create(OpCodes.Nop);
            IL.Emit(OpCodes.Ldloc, surroundingImplementation);
            IL.Emit(OpCodes.Brtrue, skipPrint);

            IL.Append(skipPrint);
            IL.Emit(OpCodes.Ldloc, surroundingImplementation);
            IL.Emit(OpCodes.Brfalse, skipInvoke);

            MethodReference aroundInvoke = module.ImportMethod<IAfterInvoke>("AfterInvoke");
            IL.Emit(OpCodes.Ldloc, surroundingImplementation);
            IL.Emit(OpCodes.Ldloc, invocationInfo);
            IL.Emit(OpCodes.Ldloc, returnValue);
            IL.Emit(OpCodes.Callvirt, aroundInvoke);

            IL.Append(skipInvoke);
        }
        private static void ImplementGetObjectData(Type originalBaseType, IEnumerable<Type> baseInterfaces,
            ModuleDefinition module, TypeDefinition targetType)
        {
            var getObjectDataMethod = (from MethodDefinition m in targetType.Methods
                where m.Name.Contains("ISerializable.GetObjectData")
                select m).First();

            var body = getObjectDataMethod.Body;
            body.Instructions.Clear();
            body.InitLocals = true;

            var IL = getObjectDataMethod.GetILGenerator();

            var proxyInterfaceType = module.ImportType<IProxy>();
            var getTypeFromHandle = module.ImportMethod<Type>("GetTypeFromHandle",
                BindingFlags.Public | BindingFlags.Static);
            var proxyObjectRefType = module.ImportType<ProxyObjectReference>();
            var setType = module.ImportMethod<SerializationInfo>("SetType",
                BindingFlags.Public | BindingFlags.Instance);
            var getInterceptor = module.ImportMethod<IProxy>("get_Interceptor");

            IL.Emit(OpCodes.Ldarg_1);
            IL.Emit(OpCodes.Ldtoken, proxyObjectRefType);
            IL.Emit(OpCodes.Call, getTypeFromHandle);
            IL.Emit(OpCodes.Callvirt, setType);

            // info.AddValue("__interceptor", __interceptor);
            var addValueMethod = typeof (SerializationInfo).GetMethod("AddValue",
                BindingFlags.Public | BindingFlags.Instance,
                null,
                new[] {typeof (string), typeof (object)},
                null);
            var addValue = module.Import(addValueMethod);

            IL.Emit(OpCodes.Ldarg_1);
            IL.Emit(OpCodes.Ldstr, "__interceptor");
            IL.Emit(OpCodes.Ldarg_0);
            IL.Emit(OpCodes.Castclass, proxyInterfaceType);
            IL.Emit(OpCodes.Callvirt, getInterceptor);
            IL.Emit(OpCodes.Callvirt, addValue);

            IL.Emit(OpCodes.Ldarg_1);
            IL.Emit(OpCodes.Ldstr, "__baseType");
            IL.Emit(OpCodes.Ldstr, originalBaseType.AssemblyQualifiedName);
            IL.Emit(OpCodes.Callvirt, addValue);

            var baseInterfaceCount = baseInterfaces.Count();

            // Save the number of base interfaces
            var integerType = module.ImportType<Int32>();
            IL.Emit(OpCodes.Ldarg_1);
            IL.Emit(OpCodes.Ldstr, "__baseInterfaceCount");
            IL.Emit(OpCodes.Ldc_I4, baseInterfaceCount);
            IL.Emit(OpCodes.Box, integerType);
            IL.Emit(OpCodes.Callvirt, addValue);

            var index = 0;
            foreach (var baseInterface in baseInterfaces)
            {
                IL.Emit(OpCodes.Ldarg_1);
                IL.Emit(OpCodes.Ldstr, string.Format("__baseInterface{0}", index++));
                IL.Emit(OpCodes.Ldstr, baseInterface.AssemblyQualifiedName);
                IL.Emit(OpCodes.Callvirt, addValue);
            }

            IL.Emit(OpCodes.Ret);
        }
        /// <summary>
        /// Pushes the current <paramref name="field"/> onto the stack.
        /// </summary>
        /// <param name="IL">The <see cref="CilWorker"/> that will be used to create the instructions.</param>
        /// <param name="field">The field that represents the <see cref="FieldInfo"/> that will be pushed onto the stack.</param>
        /// <param name="module">The module that contains the target field.</param>
        public static void PushField(this CilWorker IL, FieldReference field, ModuleDefinition module)
        {
            var getFieldFromHandle = module.ImportMethod<FieldInfo>("GetFieldFromHandle",
                typeof (RuntimeFieldHandle),
                typeof (RuntimeTypeHandle));

            var declaringType = GetDeclaringType(field.DeclaringType);

            IL.Emit(OpCodes.Ldtoken, field);
            IL.Emit(OpCodes.Ldtoken, declaringType);
            IL.Emit(OpCodes.Call, getFieldFromHandle);
        }
        public void ImportReferences(ModuleDefinition module)
        {
            // Static method imports
            _getStaticActivator = module.ImportMethod("GetActivator", typeof(TypeActivatorRegistry), BindingFlags.Public | BindingFlags.Static);
            _getTypeFromHandle = module.ImportMethod<Type>("GetTypeFromHandle", BindingFlags.Public | BindingFlags.Static);

            // Constructor imports
            _methodActivationContextCtor = module.ImportConstructor<TypeActivationContext>(typeof(object), typeof(MethodBase), typeof(Type), typeof(object[]));

            // Instance method imports
            _objectListCtor = module.ImportConstructor<List<object>>(new Type[0]);
            _toArrayMethod = module.ImportMethod<List<object>>("ToArray", new Type[0]);
            _addMethod = module.ImportMethod<List<object>>("Add", new Type[] { typeof(object) });
            _reverseMethod = module.ImportMethod<List<object>>("Reverse", new Type[0]);
            _canActivate = module.ImportMethod<ITypeActivator>("CanActivate");
            _getItem = module.ImportMethod<List<object>>("get_Item", new Type[] { typeof(int) });

            var createInstanceMethod = typeof(IActivator<ITypeActivationContext>).GetMethod("CreateInstance");

            _createInstance = module.Import(createInstanceMethod);
        }
        public void DefineGetAllInstancesMethod(TypeDefinition containerType, ModuleDefinition module, 
            IDictionary<IDependency, IImplementation> serviceMap)
        {
            var targetMethods = new List<MethodDefinition>();
            foreach (MethodDefinition method in containerType.Methods)
            {
                if (method.Name != "GetAllInstances")
                    continue;

                targetMethods.Add(method);
            }

            var getAllInstancesMethod = targetMethods[0];

            // Remove the stub implementation
            var body = getAllInstancesMethod.Body;
            var IL = body.GetILProcessor();

            body.InitLocals = true;
            body.Instructions.Clear();

            var listVariable = getAllInstancesMethod.AddLocal<List<object>>();
            var listCtor = module.ImportConstructor<List<object>>();
            IL.Emit(OpCodes.Newobj, listCtor);
            IL.Emit(OpCodes.Stloc, listVariable);

            // Group the dependencies by type
            var dependenciesByType = new HashList<System.Type, IDependency>();
            foreach (var dependency in serviceMap.Keys)
            {
                var serviceType = dependency.ServiceType;
                dependenciesByType.Add(serviceType, dependency);
            }

            var getTypeFromHandleMethod = typeof(System.Type).GetMethod("GetTypeFromHandle", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
            var getTypeFromHandle = module.Import(getTypeFromHandleMethod);
            var addItem = module.ImportMethod<List<object>>("Add");

            var currentService = getAllInstancesMethod.AddLocal<object>();

            foreach (var currentType in dependenciesByType.Keys)
            {
                var currentTypeRef = module.Import(currentType);

                var currentList = dependenciesByType[currentType];
                if (currentList.Count == 0)
                    continue;

                var skipAdd = IL.Create(OpCodes.Nop);
                IL.Emit(OpCodes.Ldarg_1);
                IL.Emit(OpCodes.Ldtoken, currentTypeRef);
                IL.Emit(OpCodes.Call, getTypeFromHandle);
                IL.Emit(OpCodes.Ceq);
                IL.Emit(OpCodes.Brfalse, skipAdd);

                foreach (var dependency in currentList)
                {
                    IL.Emit(OpCodes.Ldloc, listVariable);

                    var implementation = serviceMap[dependency];
                    implementation.Emit(dependency, serviceMap, getAllInstancesMethod);

                    IL.Emit(OpCodes.Stloc, currentService);

                    // Call IInitialize.Initialize(container) on the current service type
                    _initializer.Initialize(IL, module, currentService);

                    IL.Emit(OpCodes.Ldloc, currentService);
                    IL.Emit(OpCodes.Callvirt, addItem);
                }

                IL.Append(skipAdd);
            }

            var skipOtherContainerCall = IL.Create(OpCodes.Nop);

            var getNextContainer = module.ImportMethod<IMicroContainer>("get_NextContainer");
            var otherContainer = getAllInstancesMethod.AddLocal<IMicroContainer>();

            // var otherContainer = this.NextContainer;
            IL.Emit(OpCodes.Ldarg_0);
            IL.Emit(OpCodes.Callvirt, getNextContainer);
            IL.Emit(OpCodes.Stloc, otherContainer);

            // if (otherContainer != null && this != otherContainer) {
            IL.Emit(OpCodes.Ldloc, otherContainer);
            IL.Emit(OpCodes.Brfalse, skipOtherContainerCall);

            IL.Emit(OpCodes.Ldloc, otherContainer);
            IL.Emit(OpCodes.Ldarg_0);
            IL.Emit(OpCodes.Ceq);
            IL.Emit(OpCodes.Brtrue, skipOtherContainerCall);

            // var otherInstances = NextContainer.GetAllInstances(type);
            var otherGetAllInstancesMethod = module.ImportMethod<IMicroContainer>("GetAllInstances");

            IL.Emit(OpCodes.Ldloc, listVariable);
            IL.Emit(OpCodes.Ldloc, otherContainer);
            IL.Emit(OpCodes.Ldarg_1);
            IL.Emit(OpCodes.Callvirt, otherGetAllInstancesMethod);

            // resultList.AddRange(otherInstances);
            var addRangeMethod = module.ImportMethod<List<object>>("AddRange");
            IL.Emit(OpCodes.Callvirt, addRangeMethod);

            // }

            // Cast the results down to an IEnumerable<object>
            var enumerableType = module.ImportType<IEnumerable<object>>();
            IL.Append(skipOtherContainerCall);
            IL.Emit(OpCodes.Ldloc, listVariable);
            IL.Emit(OpCodes.Isinst, enumerableType);
            IL.Emit(OpCodes.Ret);
        }
Esempio n. 12
0
        /// <summary>
        /// Pushes the current <paramref name="method"/> onto the stack.
        /// </summary>
        /// <param name="IL">The <see cref="CilWorker"/> that will be used to create the instructions.</param>
        /// <param name="method">The method that represents the <see cref="MethodInfo"/> that will be pushed onto the stack.</param>
        /// <param name="module">The module that contains the host method.</param>
        public static void PushMethod(this CilWorker IL, MethodReference method, ModuleDefinition module)
        {
            var getMethodFromHandle = module.ImportMethod<MethodBase>("GetMethodFromHandle",
                typeof (RuntimeMethodHandle),
                typeof (RuntimeTypeHandle));

            var declaringType = method.DeclaringType;

            // Instantiate the generic type before determining
            // the current method
            if (declaringType.GenericParameters.Count > 0)
            {
                var genericType = new GenericInstanceType(declaringType);
                foreach (GenericParameter parameter in declaringType.GenericParameters)
                {
                    genericType.GenericArguments.Add(parameter);
                }

                declaringType = genericType;
            }

            IL.Emit(OpCodes.Ldtoken, method);
            IL.Emit(OpCodes.Ldtoken, declaringType);
            IL.Emit(OpCodes.Call, getMethodFromHandle);
        }
Esempio n. 13
0
        /// <summary>
        /// Saves the generic type arguments that were used to construct the method.
        /// </summary>
        /// <param name="IL">The <see cref="CilWorker"/> that will be used to create the instructions.</param>
        /// <param name="method">The target method whose generic type arguments (if any) will be saved into the <paramref name="typeArguments">local variable</paramref>.</param>
        /// <param name="module">The module that contains the host method.</param>
        /// <param name="typeArguments">The local variable that will store the resulting array of <see cref="Type"/> objects.</param>
        public static void PushGenericArguments(this CilWorker IL, IGenericParameterProvider method,
            ModuleDefinition module, VariableDefinition typeArguments)
        {
            var getTypeFromHandle = module.ImportMethod<Type>("GetTypeFromHandle",
                BindingFlags.Public | BindingFlags.Static);
            var genericParameterCount = method.GenericParameters.Count;

            var genericParameters = method.GenericParameters;
            for (var index = 0; index < genericParameterCount; index++)
            {
                var current = genericParameters[index];

                IL.Emit(OpCodes.Ldloc, typeArguments);
                IL.Emit(OpCodes.Ldc_I4, index);
                IL.Emit(OpCodes.Ldtoken, current);
                IL.Emit(OpCodes.Call, getTypeFromHandle);
                IL.Emit(OpCodes.Stelem_Ref);
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Emits the instructions that introduce the <see cref="IContainerPlugin"/> instances to the current <see cref="IMicroContainer"/> instance.
        /// </summary>
        /// <param name="module">The target module.</param>
        /// <param name="dependencyContainer">The <see cref="IDependencyContainer"/> instance that contains the services that will be instantiated by compiled container.</param>
        /// <param name="il">The current <see cref="ILProcessor"/> instance that points to the current method body.</param>
        private void InitializeContainerPlugins(ModuleDefinition module, IDependencyContainer dependencyContainer, ILProcessor il)
        {
            var pluginDependencies = new List<IDependency>(dependencyContainer.Dependencies);

            Predicate<IDependency> predicate = dependency =>
                                                   {
                                                       if (dependency.ServiceType != typeof(IContainerPlugin))
                                                           return false;

                                                       var matches = dependencyContainer.GetImplementations(dependency, false);
                                                       var matchList = new List<IImplementation>(matches);

                                                       return matchList.Count > 0;
                                                   };

            pluginDependencies = pluginDependencies.FindAll(predicate);

            var getTypeFromHandleMethod = typeof(System.Type).GetMethod("GetTypeFromHandle", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
            var getTypeFromHandle = module.Import(getTypeFromHandleMethod);
            var getInstanceMethod = module.ImportMethod<IMicroContainer>("GetInstance");
            foreach (var currentDependency in pluginDependencies)
            {
                var currentType = module.Import(currentDependency.ServiceType);
                var serviceName = currentDependency.ServiceName;

                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldtoken, currentType);
                il.Emit(OpCodes.Call, getTypeFromHandle);

                var loadString = serviceName == null
                                     ? il.Create(OpCodes.Ldnull)
                                     : il.Create(OpCodes.Ldstr, serviceName);
                il.Append(loadString);

                il.Emit(OpCodes.Callvirt, getInstanceMethod);
                il.Emit(OpCodes.Pop);
            }
        }
 private static void InvokeInterceptor(ModuleDefinition module, CilWorker IL,
     VariableDefinition methodReplacement, TypeReference returnType, VariableDefinition invocationInfo)
 {
     var interceptMethod = module.ImportMethod<IInterceptor>("Intercept");
     IL.Emit(OpCodes.Ldloc, methodReplacement);
     IL.Emit(OpCodes.Ldloc, invocationInfo);
     IL.Emit(OpCodes.Callvirt, interceptMethod);
     IL.PackageReturnValue(module, returnType);
 }
 public override void ImportReferences(ModuleDefinition module)
 {
     _getCurrentMethod = module.ImportMethod<MethodBase>("GetCurrentMethod",
                                                         BindingFlags.Public | BindingFlags.Static);
     _emitter.ImportReferences(module);
 }
Esempio n. 17
0
        /// <summary>
        /// Adds references to the target module.
        /// </summary>
        /// <param name="module">The module that will be modified.</param>
        public override void ImportReferences(ModuleDefinition module)
        {
            var parameterTypes = new[] {typeof (object), typeof (MethodBase), typeof (FieldInfo), typeof (Type)};

            _fieldInterceptionHostType = module.ImportType<IFieldInterceptionHost>();

            _fieldContextCtor = module.ImportConstructor<FieldInterceptionContext>(parameterTypes);
            module.ImportMethod<FieldInfo>("GetFieldFromHandle",
                new[] {typeof (RuntimeFieldHandle), typeof (RuntimeTypeHandle)});
            module.ImportMethod<object>("GetType");
            _getInterceptor = module.ImportMethod<FieldInterceptorRegistry>("GetInterceptor");
            _getInstanceInterceptor = module.ImportMethod<IFieldInterceptionHost>("get_FieldInterceptor");
            _canIntercept = module.ImportMethod<IFieldInterceptor>("CanIntercept");

            _getValue = module.ImportMethod<IFieldInterceptor>("GetValue");
            _setValue = module.ImportMethod<IFieldInterceptor>("SetValue");
        }
Esempio n. 18
0
        public override void ImportReferences(ModuleDefinition module)
        {
            var types = new[] { typeof(object),
                                 typeof(MethodBase),
                                 typeof(StackTrace),
                                 typeof(Type[]),
                                 typeof(Type[]),
                                 typeof(Type),
                                 typeof(object[]) };

            _invocationInfoCtor = module.ImportConstructor<InvocationInfo>(types);
            _stackCtor = module.ImportConstructor<Stack<object>>(new Type[0]);

            _pushMethod = module.ImportMethod<Stack<object>>("Push");
            _popMethod = module.ImportMethod<Stack<object>>("Pop");
            _toArray = module.ImportMethod<Stack<object>>("ToArray");
            _getProvider = module.ImportMethod<IMethodReplacementHost>("get_MethodCallReplacementProvider");
            _getStaticProvider = module.ImportMethod("GetProvider", typeof(MethodCallReplacementProviderRegistry));

            _canReplace = module.ImportMethod<IMethodReplacementProvider>("CanReplace");
            _getReplacement = module.ImportMethod<IMethodReplacementProvider>("GetMethodReplacement");
            _hostInterfaceType = module.ImportType<IMethodReplacementHost>();
            _intercept = module.ImportMethod<IInterceptor>("Intercept");
        }
Esempio n. 19
0
        /// <summary>
        /// Pushes a <paramref name="Type"/> instance onto the stack.
        /// </summary>
        /// <param name="IL">The <see cref="CilWorker"/> that will be used to create the instructions.</param>
        /// <param name="type">The type that represents the <see cref="Type"/> that will be pushed onto the stack.</param>
        /// <param name="module">The module that contains the host method.</param>
        public static void PushType(this CilWorker IL, TypeReference type, ModuleDefinition module)
        {
            var getTypeFromHandle = module.ImportMethod<Type>("GetTypeFromHandle",
                typeof (RuntimeTypeHandle));

            // Instantiate the generic type before pushing it onto the stack
            var declaringType = GetDeclaringType(type);

            IL.Emit(OpCodes.Ldtoken, declaringType);
            IL.Emit(OpCodes.Call, getTypeFromHandle);
        }
Esempio n. 20
0
 /// <summary>
 /// Saves the current method signature of a method into an array
 /// of <see cref="System.Type"/> objects. This can be used to determine the
 /// signature of methods with generic type parameters or methods that have
 /// parameters that are generic parameters specified by the type itself.
 /// </summary>
 /// <param name="IL">The <see cref="CilWorker"/> that will be used to create the instructions.</param>
 /// <param name="method">The target method whose generic type arguments (if any) will be saved into the local variable .</param>
 /// <param name="module">The module that contains the host method.</param>
 /// <param name="parameterTypes">The local variable that will store the current method signature.</param>
 public static void SaveParameterTypes(this CilWorker IL, MethodReference method, ModuleDefinition module,
     VariableDefinition parameterTypes)
 {
     var getTypeFromHandle = module.ImportMethod<Type>("GetTypeFromHandle",
         BindingFlags.Public | BindingFlags.Static);
     var parameterCount = method.Parameters.Count;
     for (var index = 0; index < parameterCount; index++)
     {
         var current = method.Parameters[index];
         IL.Emit(OpCodes.Ldloc, parameterTypes);
         IL.Emit(OpCodes.Ldc_I4, index);
         IL.Emit(OpCodes.Ldtoken, current.ParameterType);
         IL.Emit(OpCodes.Call, getTypeFromHandle);
         IL.Emit(OpCodes.Stelem_Ref);
     }
 }
Esempio n. 21
0
        public override void ImportReferences(ModuleDefinition module)
        {
            // Keep track of the module that contains the ITypeFilter type
            // so that the InterceptMethodCalls class will skip
            // trying to intercept types within the LinFu.Aop.Cecil assembly
            var typeFilterType = module.ImportType<ITypeFilter>();
            _linfuAopModule = typeFilterType.Module;

            var activatorHostType = module.ImportType<IActivatorHost>();
            _linfuAopInterfaceModule = activatorHostType.Module;

            var types = new[] { typeof(object),
                                 typeof(MethodBase),
                                 typeof(StackTrace),
                                 typeof(Type[]),
                                 typeof(Type[]),
                                 typeof(Type),
                                 typeof(object[]) };

            _invocationInfoCtor = module.ImportConstructor<InvocationInfo>(types);
            _stackCtor = module.ImportConstructor<Stack<object>>(new Type[0]);

            _pushMethod = module.ImportMethod<Stack<object>>("Push");
            _popMethod = module.ImportMethod<Stack<object>>("Pop");
            _toArray = module.ImportMethod<Stack<object>>("ToArray");
            _getProvider = module.ImportMethod<IMethodReplacementHost>("get_MethodCallReplacementProvider");
            _getStaticProvider = module.ImportMethod("GetProvider", typeof(MethodCallReplacementProviderRegistry));

            _canReplace = module.ImportMethod<IMethodReplacementProvider>("CanReplace");
            _getReplacement = module.ImportMethod<IMethodReplacementProvider>("GetMethodReplacement");
            _hostInterfaceType = module.ImportType<IMethodReplacementHost>();
            _intercept = module.ImportMethod<IInterceptor>("Intercept");
        }
Esempio n. 22
0
        /// <summary>
        /// Modifies the default constructor of a container type so that the jump labels used in the <see cref="IMicroContainer.GetInstance"/> implementation
        /// will be precalculated every time the compiled container is instantiated.
        /// </summary>
        /// <param name="module">The target module.</param>
        /// <param name="jumpTargetField">The field that holds the jump entries.</param>
        /// <param name="targetType">The container type.</param>
        /// <param name="getServiceHash">The hash calculation method.</param>
        /// <param name="serviceMap">The collection that contains the current list of dependencies and their respective implementations.</param>
        /// <param name="jumpTargets">A dictionary that maps dependencies to their respective label indexes.</param>
        private static void AddJumpEntries(ModuleDefinition module, FieldDefinition jumpTargetField, TypeDefinition targetType, MethodReference getServiceHash, IDictionary<IDependency, IImplementation> serviceMap, IDictionary<IDependency, int> jumpTargets)
        {
            var defaultContainerConstructor = targetType.GetDefaultConstructor();

            var body = defaultContainerConstructor.Body;
            var il = body.GetILProcessor();

            // Remove the last instruction and replace it with the jump entry
            // initialization instructions
            RemoveLastInstruction(body);

            // Initialize the jump targets in the default container constructor
            var getTypeFromHandleMethod = typeof(System.Type).GetMethod("GetTypeFromHandle", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
            var getTypeFromHandle = module.Import(getTypeFromHandleMethod);

            // __jumpTargets = new Dictionary<int, int>();
            var dictionaryCtor = module.ImportConstructor<Dictionary<int, int>>();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Newobj, dictionaryCtor);
            il.Emit(OpCodes.Stfld, jumpTargetField);

            var addMethod = module.ImportMethod<Dictionary<int, int>>("Add");
            var index = 0;
            foreach (var dependency in serviceMap.Keys)
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, jumpTargetField);

                var serviceType = dependency.ServiceType;
                var serviceTypeRef = module.Import(serviceType);

                // Push the service type
                il.Emit(OpCodes.Ldtoken, serviceTypeRef);
                il.Emit(OpCodes.Call, getTypeFromHandle);

                // Push the service name
                var pushName = dependency.ServiceName == null ? il.Create(OpCodes.Ldnull) : il.Create(OpCodes.Ldstr, dependency.ServiceName);
                il.Append(pushName);

                // Calculate the hash code using the service type and service name
                il.Emit(OpCodes.Call, getServiceHash);

                // Map the current dependency to the index
                // that will be used in the GetInstance switch statement
                jumpTargets[dependency] = index;

                il.Emit(OpCodes.Ldc_I4, index++);
                il.Emit(OpCodes.Callvirt, addMethod);
            }
        }