コード例 #1
0
        public void Inject()
        {
            var typeName = Guid.NewGuid().ToString("N");

            AssemblyManager.Manage((assembly) =>
            {
                var toStringAttributeCtor = assembly.MainModule.Import(
                    typeof(ToStringAttribute).GetConstructor(Type.EmptyTypes));
                var attribute = new CustomAttribute(toStringAttributeCtor);
                var type      = AssemblyManager.AddType(assembly, typeName);
                type.CustomAttributes.Add(attribute);
            }, (assembly) =>
            {
                var injector = new ToStringAttribute();

                var targetType = (from type in assembly.MainModule.GetAllTypes()
                                  where type.Name == typeName
                                  select type).First();

                Assert.AreEqual(0, targetType.Methods.Count);
                injector.Inject(targetType);
                Assert.AreEqual(1, targetType.Methods.Count);

                var instructions = targetType.Methods[0].Body.Instructions;
                Assert.AreEqual(2, instructions.Count);
                Assert.AreEqual(OpCodes.Ldstr, instructions[0].OpCode);
                Assert.AreEqual(OpCodes.Ret, instructions[1].OpCode);
            }, false);
        }
コード例 #2
0
        public void InjectWhenTypeHasValueTypeProperty()
        {
            var typeName     = Guid.NewGuid().ToString("N");
            var propertyName = Guid.NewGuid().ToString("N");

            AssemblyManager.Manage((assembly) =>
            {
                var toStringAttributeCtor = assembly.MainModule.Import(
                    typeof(ToStringAttribute).GetConstructor(Type.EmptyTypes));
                var attribute = new CustomAttribute(toStringAttributeCtor);
                var type      = AssemblyManager.AddType(assembly, typeName);
                type.CustomAttributes.Add(attribute);

                var method = AssemblyManager.AddMethod(type, "get_" + propertyName,
                                                       new List <ParameterDefinition>(), assembly.MainModule.Import(typeof(int)));
                method.CallingConvention = MethodCallingConvention.ThisCall;
                method.IsStatic          = false;
                method.IsHideBySig       = true;

                var processor = method.Body.GetILProcessor();
                processor.Append(Instruction.Create(OpCodes.Ldc_I4_0));
                processor.Append(Instruction.Create(OpCodes.Ret));

                var property = new PropertyDefinition(propertyName, PropertyAttributes.None,
                                                      assembly.MainModule.Import(typeof(int)));
                property.GetMethod = method;
                type.Properties.Add(property);
            }, (assembly) =>
            {
                var injector = new ToStringAttribute();

                var targetType = (from type in assembly.MainModule.GetAllTypes()
                                  where type.Name == typeName
                                  select type).First();

                Assert.AreEqual(1, targetType.Methods.Count);
                injector.Inject(targetType);
                Assert.AreEqual(2, targetType.Methods.Count);

                var targetMethod = (from type in assembly.MainModule.GetAllTypes()
                                    where type.Name == typeName
                                    from method in type.GetMethods()
                                    where method.Name == "ToString"
                                    select method).First();
                var instructions = targetMethod.Body.Instructions;
                Assert.AreEqual(9, instructions.Count);
                Assert.AreEqual(OpCodes.Newobj, instructions[0].OpCode);
                Assert.AreEqual(OpCodes.Ldstr, instructions[1].OpCode);
                Assert.AreEqual(OpCodes.Call, instructions[2].OpCode);
                Assert.AreEqual(OpCodes.Ldarg_0, instructions[3].OpCode);
                Assert.AreEqual(OpCodes.Call, instructions[4].OpCode);
                Assert.AreEqual(OpCodes.Box, instructions[5].OpCode);
                Assert.AreEqual(OpCodes.Callvirt, instructions[6].OpCode);
                Assert.AreEqual(OpCodes.Callvirt, instructions[7].OpCode);
                Assert.AreEqual(OpCodes.Ret, instructions[8].OpCode);
            }, false);
        }
コード例 #3
0
        public void InjectWhenToStringMethodExistsOnType()
        {
            var typeName = Guid.NewGuid().ToString("N");

            AssemblyManager.Manage((assembly) =>
            {
                var toStringAttributeCtor = assembly.MainModule.Import(
                    typeof(ToStringAttribute).GetConstructor(Type.EmptyTypes));
                var attribute = new CustomAttribute(toStringAttributeCtor);
                var type      = AssemblyManager.AddType(assembly, typeName);
                type.CustomAttributes.Add(attribute);

                var method = AssemblyManager.AddMethod(type, "ToString",
                                                       new List <ParameterDefinition>(), assembly.MainModule.Import(typeof(string)));
                method.CallingConvention = MethodCallingConvention.ThisCall;
                method.IsVirtual         = true;
                method.IsStatic          = false;
                method.IsHideBySig       = true;

                var processor = method.Body.GetILProcessor();
                processor.Append(Instruction.Create(OpCodes.Ldnull));
                processor.Append(Instruction.Create(OpCodes.Ret));
            }, (assembly) =>
            {
                var injector = new ToStringAttribute();

                var targetType = (from type in assembly.MainModule.GetAllTypes()
                                  where type.Name == typeName
                                  select type).First();

                Assert.AreEqual(1, targetType.Methods.Count);
                injector.Inject(targetType);
                Assert.AreEqual(1, targetType.Methods.Count);

                var instructions = targetType.Methods[0].Body.Instructions;
                Assert.AreEqual(2, instructions.Count);
                Assert.AreEqual(OpCodes.Ldnull, instructions[0].OpCode);
                Assert.AreEqual(OpCodes.Ret, instructions[1].OpCode);
            }, false);
        }