Ejemplo n.º 1
0
 /// <summary>
 /// Introduces the member.
 /// </summary>
 /// <param name="moduleDefinition">The module definition.</param>
 /// <param name="memberName">Name of the member.</param>
 /// <param name="memberType">Type of the member.</param>
 /// <param name="isStatic">if set to <c>true</c> [is static].</param>
 /// <param name="adviceType">The advice.</param>
 /// <param name="advisedType">The type definition.</param>
 /// <param name="markerAttribute">The marker attribute ctor.</param>
 /// <param name="introducedMemberName">Name of the introduced member.</param>
 /// <param name="isNotSerialized">if set to <c>true</c> [is not serialized].</param>
 /// <param name="context">The context.</param>
 private void IntroduceMember(ModuleDef moduleDefinition, string memberName, ITypeDefOrRef memberType, bool isStatic,
                              ITypeDefOrRef adviceType, TypeDef advisedType, ICustomAttributeType markerAttribute, string introducedMemberName, bool isNotSerialized, WeavingContext context)
 {
     if (IsIntroduction(memberType, out var introducedFieldType, out var isShared, context))
     {
         var introducedFieldName = IntroductionRules.GetName(adviceType.Namespace, adviceType.Name, introducedMemberName, memberName, isShared);
         lock (advisedType.Fields)
         {
             if (advisedType.Fields.All(f => f.Name != introducedFieldName))
             {
                 var fieldAttributes = (InjectAsPrivate ? FieldAttributes.Private : FieldAttributes.Public)
                                       | (isNotSerialized ? FieldAttributes.NotSerialized : 0);
                 if (isStatic)
                 {
                     fieldAttributes |= FieldAttributes.Static;
                 }
                 Logging.WriteDebug("Introduced field type '{0}'", introducedFieldType.FullName);
                 var introducedFieldTypeReference = TypeImporter.Import(moduleDefinition, introducedFieldType.ToTypeSig());
                 var introducedField = new FieldDefUser(introducedFieldName, new FieldSig(introducedFieldTypeReference), fieldAttributes);
                 introducedField.CustomAttributes.Add(new CustomAttribute(markerAttribute));
                 advisedType.Fields.Add(introducedField);
             }
         }
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Weaves the info advices for the given type.
        /// </summary>
        /// <param name="infoAdvisedType">Type of the module.</param>
        /// <param name="moduleDefinition">The module definition.</param>
        /// <param name="useWholeAssembly">if set to <c>true</c> [use whole assembly].</param>
        private void WeaveInfoAdvices(TypeDef infoAdvisedType, ModuleDef moduleDefinition, bool useWholeAssembly)
        {
            var invocationType = TypeResolver.Resolve(moduleDefinition, typeof(Invocation));

            if (invocationType == null)
            {
                return;
            }
            var proceedRuntimeInitializersReference = (from m in invocationType.Methods
                                                       where m.IsStatic && m.Name == nameof(Invocation.ProcessInfoAdvices)
                                                       let parameters = m.Parameters
                                                                        where parameters.Count == 1 &&
                                                                        parameters[0].Type.SafeEquivalent(
                                                           moduleDefinition.SafeImport(useWholeAssembly ? typeof(Assembly) : typeof(Type)).ToTypeSig())
                                                                        select m).SingleOrDefault();

            if (proceedRuntimeInitializersReference == null)
            {
                Logging.WriteWarning("Info advice method not found");
                return;
            }

            // the cctor needs to be called after all initialization (in case some info advices collect data)
            infoAdvisedType.Attributes &= ~TypeAttributes.BeforeFieldInit;

            const string cctorMethodName = ".cctor";
            var          staticCtor      = infoAdvisedType.Methods.SingleOrDefault(m => m.Name == cctorMethodName);
            var          newStaticCtor   = staticCtor == null;

            if (newStaticCtor)
            {
                staticCtor = new MethodDefUser(cctorMethodName, MethodSig.CreateStatic(moduleDefinition.CorLibTypes.Void),
                                               (InjectAsPrivate ? MethodAttributes.Private : MethodAttributes.Public)
                                               | MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
                staticCtor.Body = new CilBody();
                infoAdvisedType.Methods.Add(staticCtor);
            }

            var instructions = new Instructions(staticCtor.Body.Instructions, staticCtor.Module);

            var proceedMethod = moduleDefinition.SafeImport(proceedRuntimeInitializersReference);

            if (useWholeAssembly)
            {
                instructions.Emit(OpCodes.Call, moduleDefinition.SafeImport(ReflectionUtility.GetMethodInfo(() => Assembly.GetExecutingAssembly())));
            }
            else
            {
                instructions.Emit(OpCodes.Ldtoken, TypeImporter.Import(moduleDefinition, infoAdvisedType.ToTypeSig()));
                // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
                var getTypeFromHandleMethodInfo = ReflectionUtility.GetMethodInfo(() => Type.GetTypeFromHandle(new RuntimeTypeHandle()));
                instructions.Emit(OpCodes.Call, moduleDefinition.SafeImport(getTypeFromHandleMethodInfo));
            }
            instructions.Emit(OpCodes.Call, proceedMethod);
            // ret is only emitted if the method is new
            if (newStaticCtor)
            {
                instructions.Emit(OpCodes.Ret);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Weaves the info advices for the given type.
        /// </summary>
        /// <param name="infoAdvisedType">Type of the module.</param>
        /// <param name="moduleDefinition">The module definition.</param>
        /// <param name="useWholeAssembly">if set to <c>true</c> [use whole assembly].</param>
        private void WeaveInfoAdvices(TypeDef infoAdvisedType, ModuleDef moduleDefinition, bool useWholeAssembly)
        {
            var invocationType = TypeResolver.Resolve(moduleDefinition, typeof(Invocation));

            if (invocationType == null)
            {
                return;
            }
            var proceedRuntimeInitializersReference = (from m in invocationType.Methods
                                                       where m.IsStatic && m.Name == nameof(Invocation.ProcessInfoAdvices)
                                                       let parameters = m.Parameters
                                                                        where parameters.Count == 1 &&
                                                                        parameters[0].Type.SafeEquivalent(
                                                           moduleDefinition.SafeImport(useWholeAssembly ? typeof(Assembly) : typeof(Type)).ToTypeSig())
                                                                        select m).SingleOrDefault();

            if (proceedRuntimeInitializersReference == null)
            {
                Logging.WriteWarning("Info advice method not found");
                return;
            }

            var instructions  = GetCctorInstructions(infoAdvisedType);
            var proceedMethod = moduleDefinition.SafeImport(proceedRuntimeInitializersReference);

            if (useWholeAssembly)
            {
                instructions.Emit(OpCodes.Call, moduleDefinition.SafeImport(ReflectionUtility.GetMethodInfo(() => Assembly.GetExecutingAssembly())));
            }
            else
            {
                instructions.Emit(OpCodes.Ldtoken, TypeImporter.Import(moduleDefinition, infoAdvisedType.ToTypeSig()));
                // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
                var getTypeFromHandleMethodInfo = ReflectionUtility.GetMethodInfo(() => Type.GetTypeFromHandle(new RuntimeTypeHandle()));
                instructions.Emit(OpCodes.Call, moduleDefinition.SafeImport(getTypeFromHandleMethodInfo));
            }
            instructions.Emit(OpCodes.Call, proceedMethod);
        }