/// <summary>
        /// Creates the advice wrapper and adds it to implementation.
        /// </summary>
        /// <param name="interfaceMethod">The interface method.</param>
        /// <param name="implementationType">Type of the implementation.</param>
        /// <param name="injectAsPrivate">if set to <c>true</c> [inject as private].</param>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private MethodDef WeaveInterfaceMethod(MethodDef interfaceMethod, TypeDef implementationType, bool injectAsPrivate, WeavingContext context)
        {
            var module                  = implementationType.Module;
            var typeImporter            = new TypeImporter(module);
            var methodAttributes        = MethodAttributes.NewSlot | MethodAttributes.Virtual | (injectAsPrivate ? MethodAttributes.Public : MethodAttributes.Private);
            var implementationMethodSig = interfaceMethod.MethodSig.Clone();
            var implementationMethod    = new MethodDefUser(interfaceMethod.Name, /*interfaceMethod.MethodSig */ implementationMethodSig, methodAttributes);

            for (int parameterIndex = 0; parameterIndex < implementationMethod.Parameters.Count; parameterIndex++)
            {
                var parameterType = implementationMethod.Parameters[parameterIndex].Type;
                if (parameterType != null)
                {
                    var relocatedParameterType = typeImporter.TryRelocateTypeSig(parameterType) ?? parameterType;
                    implementationMethod.Parameters[parameterIndex].Type = module.Import(relocatedParameterType);
                }
            }
            if (implementationMethod.HasReturnType)
            {
                var relocatedReturnType = typeImporter.TryRelocateTypeSig(implementationMethod.ReturnType) ?? implementationMethod.ReturnType;
                implementationMethod.ReturnType = relocatedReturnType;
            }
            implementationMethod.GenericParameters.AddRange(interfaceMethod.GenericParameters);
            implementationType.Methods.Add(implementationMethod);
            var interfaceMethodRef = module.Import(interfaceMethod);

            implementationMethod.Overrides.Add(new MethodOverride(implementationMethod, interfaceMethodRef));
            WritePointcutBody(implementationMethod, null, false, context);
            return(implementationMethod);
        }
 /// <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);
             }
         }
     }
 }
        /// <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);
            }
        }
		public void ImportingMultipleAndDiscovererReturnsNullShouldCauseAnArgumentException()
		{
            var containerMock = new Mock<IContainer>();
			var typeDiscovererMock = new Mock<ITypeDiscoverer>();
			typeDiscovererMock.Setup(t => t.FindMultiple<IMultipleInterface>()).Returns((Type[])null);
			var typeImporter = new TypeImporter(containerMock.Object, typeDiscovererMock.Object);
			typeImporter.ImportMany<IMultipleInterface>();
		}
Exemple #5
0
        public void ImportingMultipleAndDiscovererReturnsNullShouldCauseAnArgumentException()
        {
            var containerMock      = new Mock <IContainer>();
            var typeDiscovererMock = new Mock <ITypeDiscoverer>();

            typeDiscovererMock.Setup(t => t.FindMultiple <IMultipleInterface>()).Returns((Type[])null);
            var typeImporter = new TypeImporter(containerMock.Object, typeDiscovererMock.Object);

            typeImporter.ImportMany <IMultipleInterface>();
        }
		public void ImportingMultipleAndThereIsOnlyOneShouldReturnThatInstance()
		{
            var containerMock = new Mock<IContainer>();
			var typeDiscovererMock = new Mock<ITypeDiscoverer>();
			typeDiscovererMock.Setup(t => t.FindMultiple<ISingleInterface>()).Returns(new[]
			                                                                            	{
																								typeof(SingleClass),
			                                                                            	});
			var typeImporter = new TypeImporter(containerMock.Object, typeDiscovererMock.Object);
			var instances = typeImporter.ImportMany<ISingleInterface>();
			Assert.That(instances.Length, Is.EqualTo(1));
			Assert.That(instances[0], Is.InstanceOf<SingleClass>());
		}
		public void ImportingMultipleShouldReturnAllInstances()
		{
		    var containerMock = new Mock<IContainer>();
			var typeDiscovererMock = new Mock<ITypeDiscoverer>();
			typeDiscovererMock.Setup(t => t.FindMultiple<IMultipleInterface>()).Returns(new[]
			                                                                            	{
																								typeof(FirstMultipleClass),
																								typeof(SecondMultipleClass)
			                                                                            	});
			var typeImporter = new TypeImporter(containerMock.Object, typeDiscovererMock.Object);
			var instances = typeImporter.ImportMany<IMultipleInterface>();
			Assert.That(instances.Length, Is.EqualTo(2));
			Assert.That(instances[0], Is.InstanceOf<FirstMultipleClass>());
			Assert.That(instances[1], Is.InstanceOf<SecondMultipleClass>());
		}
Exemple #8
0
        public void ImportingMultipleAndThereIsOnlyOneShouldReturnThatInstance()
        {
            var containerMock      = new Mock <IContainer>();
            var typeDiscovererMock = new Mock <ITypeDiscoverer>();

            containerMock.Setup(c => c.Get(typeof(SingleClass))).Returns(new SingleClass());

            typeDiscovererMock.Setup(t => t.FindMultiple <ISingleInterface>()).Returns(new[]
            {
                typeof(SingleClass),
            });
            var typeImporter = new TypeImporter(containerMock.Object, typeDiscovererMock.Object);
            var instances    = typeImporter.ImportMany <ISingleInterface>();

            Assert.That(instances.Length, Is.EqualTo(1));
            Assert.That(instances[0], Is.InstanceOf <SingleClass>());
        }
Exemple #9
0
        public void ImportingMultipleShouldReturnAllInstances()
        {
            var containerMock      = new Mock <IContainer>();
            var typeDiscovererMock = new Mock <ITypeDiscoverer>();

            containerMock.Setup(c => c.Get(typeof(FirstMultipleClass))).Returns(new FirstMultipleClass());
            containerMock.Setup(c => c.Get(typeof(SecondMultipleClass))).Returns(new SecondMultipleClass());
            typeDiscovererMock.Setup(t => t.FindMultiple <IMultipleInterface>()).Returns(new[]
            {
                typeof(FirstMultipleClass),
                typeof(SecondMultipleClass)
            });
            var typeImporter = new TypeImporter(containerMock.Object, typeDiscovererMock.Object);
            var instances    = typeImporter.ImportMany <IMultipleInterface>();

            Assert.That(instances.Length, Is.EqualTo(2));
            Assert.That(instances[0], Is.InstanceOf <FirstMultipleClass>());
            Assert.That(instances[1], Is.InstanceOf <SecondMultipleClass>());
        }
        /// <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);
        }
Exemple #11
0
        private void Given_TypeImporter()
        {
            var tldser = new TypeLibraryDeserializer(platform.Object, false, typelib);

            this.typeimporter = new TypeImporter(platform.Object, tldser, new Dictionary <string, Constant>(), typelib);
        }
Exemple #12
0
        public void ShouldPatchGenericsAndArrays()
        {
            var testTypes = GetTestTypes().ToArray();

            AreEqual(4, testTypes.Length);
            var mbs   = testTypes.SelectMany(GetMemberTypes);
            var types = mbs.Distinct().OrderBy(t => t.FullName.Length).ToArray();
            var dict  = new Dictionary <TypeReference, TypeReference>();
            var clr   = types[0];
            var my    = types[6];

            dict[ToRef(typeof(SuperClass), my)]    = ToRef(typeof(decimal), clr);
            dict[ToRef(typeof(SuperDelegate), my)] = ToRef(typeof(double), clr);
            dict[ToRef(typeof(SuperStruct), my)]   = ToRef(typeof(ulong), clr);
            dict[ToRef(typeof(SuperWeird), my)]    = ToRef(typeof(sbyte), clr);
            var imp     = new TypeImporter(clr);
            var patcher = Tuple.Create(new TypeSuggestor(dict), new TypePatcher(dict));

            AreEqual("System.String", TestSomeType(types[0], patcher, imp).FullName);
            AreEqual("System.Int32*", TestSomeType(types[1], patcher, imp).FullName);
            AreEqual("System.UInt32&", TestSomeType(types[2], patcher, imp).FullName);
            AreEqual("System.UInt32&", TestSomeType(types[3], patcher, imp).FullName);
            AreEqual("System.Single**", TestSomeType(types[4], patcher, imp).FullName);
            AreEqual("System.Int16***", TestSomeType(types[5], patcher, imp).FullName);
            AreEqual("System.Decimal", TestSomeType(types[6], patcher, imp).FullName);
            AreEqual("System.UInt64", TestSomeType(types[7], patcher, imp).FullName);
            AreEqual("System.Decimal&", TestSomeType(types[8], patcher, imp).FullName);
            AreEqual("System.Decimal&", TestSomeType(types[9], patcher, imp).FullName);
            AreEqual("System.SByte&", TestSomeType(types[10], patcher, imp).FullName);
            AreEqual("System.SByte&", TestSomeType(types[11], patcher, imp).FullName);
            AreEqual("System.Double", TestSomeType(types[12], patcher, imp).FullName);
            AreEqual("System.Double[]", TestSomeType(types[13], patcher, imp).FullName);
            AreEqual("System.Double[]", TestSomeType(types[14], patcher, imp).FullName);
            AreEqual("System.Double[][]", TestSomeType(types[15], patcher, imp).FullName);
            AreEqual("System.Double[][][]", TestSomeType(types[16], patcher, imp).FullName);
            AreEqual("System.Double[0...,0...]", TestSomeType(types[17], patcher, imp).FullName);
            AreEqual("System.Double[0...,0...,0...]", TestSomeType(types[18], patcher, imp).FullName);
            AreEqual("System.Nullable`1<System.UInt64>", TestSomeType(types[19], patcher, imp).FullName);
            AreEqual("System.Collections.Generic.ISet`1<System.UInt64>",
                     TestSomeType(types[20], patcher, imp).FullName);
            AreEqual("System.Collections.Generic.IList`1<System.UInt64>",
                     TestSomeType(types[21], patcher, imp).FullName);
            AreEqual("System.Collections.Generic.IList`1<System.Decimal>&",
                     TestSomeType(types[22], patcher, imp).FullName);
            AreEqual("System.Collections.Generic.ISet`1<System.Decimal[]>[]&",
                     TestSomeType(types[23], patcher, imp).FullName);
            AreEqual("System.Collections.Generic.ICollection`1<System.UInt64>",
                     TestSomeType(types[24], patcher, imp).FullName);
            AreEqual("System.Collections.Generic.IEnumerable`1<System.UInt64>",
                     TestSomeType(types[25], patcher, imp).FullName);
            AreEqual("System.Action`3<System.String,System.SByte,System.UInt32>",
                     TestSomeType(types[26], patcher, imp).FullName);
            AreEqual("System.Collections.Generic.IEnumerable`1<System.Double[]>",
                     TestSomeType(types[27], patcher, imp).FullName);
            AreEqual("System.Tuple`3<System.UInt64,System.String,System.Double>",
                     TestSomeType(types[28], patcher, imp).FullName);
            AreEqual("System.Collections.Generic.IDictionary`2<System.Double,System.UInt64>",
                     TestSomeType(types[29], patcher, imp).FullName);
            AreEqual(
                "System.Collections.Generic.ICollection`1<System.Collections.Generic.IEnumerable`1<System.Double[]>>",
                TestSomeType(types[30], patcher, imp).FullName);
            AreEqual(
                "System.Collections.Generic.IList`1<System.Collections.Generic.ICollection`1<System.Collections.Generic.IEnumerable`1<System.Double[]>>>",
                TestSomeType(types[31], patcher, imp).FullName);
            AreEqual(
                "System.Collections.Generic.ISet`1<System.Collections.Generic.IList`1<System.Collections.Generic.ICollection`1<System.Collections.Generic.IEnumerable`1<System.Double[]>>>>",
                TestSomeType(types[32], patcher, imp).FullName);
            AreEqual(
                "System.Collections.Generic.ISet`1<System.Collections.Generic.IList`1<System.Collections.Generic.ICollection`1<System.Collections.Generic.IEnumerable`1<System.Double[]>[]>>[]>[]",
                TestSomeType(types[33], patcher, imp).FullName);
            AreEqual(
                "System.Collections.Generic.IDictionary`2<System.Collections.Generic.IEnumerable`1<System.Double[]>,System.Collections.Generic.ISet`1<System.Collections.Generic.IList`1<System.Collections.Generic.ICollection`1<System.Tuple`2<System.Double,System.UInt64>>>>>",
                TestSomeType(types[34], patcher, imp).FullName);
            AreEqual(
                "System.Collections.Generic.IDictionary`2<System.Collections.Generic.IEnumerable`1<System.Double>[],System.Collections.Generic.ISet`1<System.Collections.Generic.IList`1<System.Collections.Generic.ICollection`1<System.Tuple`2<System.Double,System.UInt64>>>>[]>",
                TestSomeType(types[35], patcher, imp).FullName);
            AreEqual(36, types.Length);
        }