示例#1
0
        //如果method是注入函数,返回其注入类型,id,以及对应的新函数
        public static void AnalysisMethod(Dictionary <string, Dictionary <string, List <MethodDefinition> > > searchData,
                                          MethodDefinition method, out InjectType injectType, out int id, out MethodDefinition foundMethod)
        {
            int firstInstruction;

            AnalysisMethod(method, out injectType, out id, out firstInstruction);
            foundMethod = null;
            if (id >= 0)
            {
                Dictionary <string, List <MethodDefinition> > methodsOfType;
                List <MethodDefinition> overloads;
                if (searchData.TryGetValue(method.DeclaringType.FullName, out methodsOfType) &&
                    methodsOfType.TryGetValue(method.Name, out overloads))
                {
                    foreach (var overload in overloads)
                    {
                        if (overload.IsTheSame(method))
                        {
                            foundMethod = overload;
                            break;
                        }
                    }
                }
            }
        }
示例#2
0
    static void FillCoroutineMonitor(MethodDefinition target, InjectType runtimeInjectType, int methodIndex)
    {
        if (runtimeInjectType == InjectType.None)
        {
            return;
        }

        MethodBody      targetBody      = target.Body;
        FieldDefinition hostField       = null;
        var             coroutineEntity = targetBody.Variables[0].VariableType.Resolve();

        if (!target.DeclaringType.NestedTypes.Any(type => coroutineEntity == type))
        {
            return;
        }

        cursor = GetMethodNextInsertPosition(target, cursor, true);
        CopyCoroutineCreatorReference(target, coroutineEntity, ref hostField);
        var coroutineCarrier = coroutineEntity.Methods.Single(method => method.Name == "MoveNext");

        CopyCreatorArgsToCarrier(target, coroutineCarrier);
        FillBegin(coroutineCarrier, methodIndex);
        var fillInjectInfoFunc = GetCoroutineInjectInfoFiller(target, hostField);

        FillInjectMethod(coroutineCarrier, fillInjectInfoFunc, runtimeInjectType & InjectType.After);
        FillInjectMethod(coroutineCarrier, fillInjectInfoFunc, runtimeInjectType & InjectType.Before);
    }
示例#3
0
 static void FillInjectInfo(MethodDefinition target, InjectType runtimeInjectType)
 {
     FillBaseCall(target, runtimeInjectType, true);
     FillLuaMethodCall(target, runtimeInjectType == InjectType.After);
     FillBaseCall(target, runtimeInjectType, false);
     FillJumpInfo(target, runtimeInjectType == InjectType.After);
 }
示例#4
0
    static InjectType GetMethodRuntimeInjectType(MethodDefinition target)
    {
        InjectType type = injectType;

        //bool bOverrideParantMethodFlag = target.IsVirtual && target.IsReuseSlot;
        var parantMethod = target.GetBaseMethodInstance();

        if (target.IsConstructor)
        {
            type &= ~InjectType.Before;
            type &= ~InjectType.Replace;
            type &= ~InjectType.ReplaceWithPostInvokeBase;
            type &= ~InjectType.ReplaceWithPreInvokeBase;
        }
        else if (parantMethod == null || target.IsEnumerator())
        {
            type &= ~InjectType.ReplaceWithPostInvokeBase;
            type &= ~InjectType.ReplaceWithPreInvokeBase;
        }
        else if (!target.HasBody)
        {
            type &= ~InjectType.After;
            type &= ~InjectType.Before;
        }

        return(type);
    }
示例#5
0
    static void InjectMethod(AssemblyDefinition assembly, MethodDefinition target, int methodIndex)
    {
        FillBegin(target, methodIndex);
        InjectType runtimeInjectType = GetMethodRuntimeInjectType(target);

        FillInjectMethod(target, FillInjectInfo, runtimeInjectType & InjectType.After);
        FillInjectMethod(target, FillInjectInfo, runtimeInjectType & (~InjectType.After));
    }
示例#6
0
 public DialogResult ShowDialog(InjectType type)
 {
     TargetType         = type;
     OwnerType.Enabled  = false;
     OwnerPanel.Enabled = false;
     ItemType.Enabled   = false;
     return(ShowDialog());
 }
示例#7
0
    static void InjectMethod(AssemblyDefinition assembly, MethodDefinition target, int methodIndex)
    {
        target.Body.SimplifyMacros();
        FillBegin(target, methodIndex);
        InjectType runtimeInjectType = GetMethodRuntimeInjectType(target);

        FillInjectMethod(target, FillInjectInfo, runtimeInjectType & InjectType.After);
        FillInjectMethod(target, FillInjectInfo, runtimeInjectType & (~InjectType.After));
        target.Body.OptimizeMacros();
    }
示例#8
0
    static void InjectCoroutine(AssemblyDefinition assembly, MethodDefinition target, int methodIndex)
    {
        InjectType runtimeInjectType = GetMethodRuntimeInjectType(target);

        if (runtimeInjectType == InjectType.None)
        {
            return;
        }

        FillBegin(target, methodIndex);
        FillReplaceCoroutine(target, runtimeInjectType & InjectType.Replace);
        FillCoroutineMonitor(target, runtimeInjectType & (~InjectType.Replace), methodIndex);
    }
示例#9
0
 public virtual void Inject(InjectType type)
 {
     try
     {
         using (var frm = new InjectForm())
         {
             if (frm.ShowDialog(type) == DialogResult.OK)
             {
                 ItemInjected(this, EventArgs.Empty);
             }
         }
     }
     catch (AssemblyResolutionException arException)
     {
         ShowMessage(string.Format("Unable to resolve assembly {0}, please load it prior to injection.", arException.AssemblyReference.Name));
     }
 }
示例#10
0
        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="serviceLifetime"></param>
        /// <param name="assemblies"></param>
        /// <returns></returns>
        public static IIoc RegisterTypeByAssembly(this IIoc ioc, ServiceLifetime serviceLifetime, InjectType injectMode, params Assembly[] assemblies)
        {
            if (assemblies.Length <= 0)
            {
                return(ioc);
            }
            Type            iocIgnoreAttributeType = typeof(IocIgnoreAttribute);
            Type            liftTimeAttributeType  = typeof(LiftTimeAttribute);
            Type            injectType             = typeof(InjectAttribute);
            ServiceLifetime liftTime;
            InjectType      injectModeTmp;

            foreach (var item in assemblies)
            {
                foreach (var item1 in item.ExportedTypes)
                {
                    if (item1.IsClass && !item1.IsAbstract)
                    {
                        if (item1.IsDefined(iocIgnoreAttributeType))
                        {
                            continue;
                        }
                        if (item1.IsDefined(liftTimeAttributeType))
                        {
                            var liftTimeAttribute = item1.GetCustomAttribute <LiftTimeAttribute>();
                            liftTime = liftTimeAttribute.ServiceLifetime;
                        }
                        else
                        {
                            liftTime = serviceLifetime;
                        }
                        if (item1.IsDefined(injectType))
                        {
                            var obj = item1.GetCustomAttribute <InjectAttribute>();
                            injectModeTmp = obj.InjectMode;
                        }
                        else
                        {
                            injectModeTmp = injectMode;
                        }
                        ioc.AddType(item1, item1, liftTime, injectModeTmp);
                    }
                }
            }
            return(ioc);
        }
示例#11
0
        public static void AnalysisMethod(MethodDefinition method, out InjectType injectType, out int id,
                                          out int firstInstruction)
        {
            firstInstruction = 0;

            if (method.Body == null || method.Body.Instructions == null)
            {
                goto NotInjectYet;
            }

            var instructions = method.Body.Instructions;

            if (instructions.Count > 2 && instructions[1].OpCode.Code == Code.Call)
            {
                var callMethod = instructions[1].Operand as MethodReference;
                if (callMethod.DeclaringType.FullName == "IFix.Core.SwitchFlag" && callMethod.Name == "Get")
                {
                    injectType = InjectType.Switch;
                }
                else if (callMethod.DeclaringType.FullName == "IFix.WrappersManagerImpl" && callMethod.Name == "Get")
                {
                    injectType = InjectType.Redirect;
                }
                else
                {
                    goto NotInjectYet;
                }
                id = getLDCOperand(instructions[0]);
                for (int i = 0; i < instructions.Count; i++)
                {
                    if (instructions[i].OpCode.Code == Code.Ret)
                    {
                        firstInstruction = i + 1;
                        break;
                    }
                }
                return;
            }

NotInjectYet:
            injectType = InjectType.None;
            id         = -1;
        }
示例#12
0
    static void FillBaseCall(MethodDefinition target, InjectType runtimeInjectType, bool preCall)
    {
        MethodBody  targetBody        = target.Body;
        ILProcessor il                = targetBody.GetILProcessor();
        InjectType  curBaseInjectType = preCall ? InjectType.ReplaceWithPreInvokeBase : InjectType.ReplaceWithPostInvokeBase;

        if (runtimeInjectType.HasFlag(curBaseInjectType))
        {
            Instruction end = il.Create(OpCodes.Nop);
            il.InsertBefore(cursor, end);
            il.InsertBefore(end, il.Create(OpCodes.Ldloc, flagDef));
            il.InsertBefore(end, il.Create(OpCodes.Ldc_I4, (int)curBaseInjectType));
            il.InsertBefore(end, il.Create(OpCodes.Bne_Un, end));

            FillArgs(target, end, PostProcessBaseMethodArg);
            il.InsertBefore(end, il.Create(OpCodes.Call, target.GetBaseMethodInstance()));
            if (!target.ReturnVoid())
            {
                il.InsertBefore(end, il.Create(OpCodes.Pop));
            }
        }
    }
示例#13
0
 public TypeItemObject(Type serviceType, Type implementationType, object[] parameters, ServiceLifetime serviceLifetime, InjectType injectMode)
 {
     if (!(serviceType.IsClass || serviceType.IsAbstract || serviceType.IsInterface))
     {
         throw new Exception("不是class类型");
     }
     ServiceType        = serviceType;
     ImplementationType = implementationType;
     ServiceLifetime    = serviceLifetime;
     Parameters         = parameters;
     InjectMode         = injectMode;
     if (InjectMode == InjectType.Constructor)
     {
         getInstanceFunc = GetInstance;
     }
     else if (InjectMode == InjectType.Property)
     {
         getInstanceFunc = GetInstanceByProperty;
     }
     else if (InjectMode == (InjectType.Constructor | InjectType.Property))
     {
         getInstanceFunc = GetInstanceByPropertyAndConstructor;
     }
 }
示例#14
0
    static void FillReplaceCoroutine(MethodDefinition target, InjectType runtimeInjectType)
    {
        if (runtimeInjectType == InjectType.None)
        {
            return;
        }

        MethodBody  targetBody = target.Body;
        ILProcessor il         = targetBody.GetILProcessor();

        cursor = GetMethodNextInsertPosition(target, null, false);

        if (cursor != null)
        {
            il.InsertBefore(cursor, il.Create(OpCodes.Ldloc, flagDef));
            il.InsertBefore(cursor, il.Create(ldcI4s[(int)InjectType.Replace / 2]));
            il.InsertBefore(cursor, il.Create(OpCodes.Bne_Un, cursor));

            il.InsertBefore(cursor, il.Create(OpCodes.Ldloc, funcDef));
            FillArgs(target, cursor, null);
            il.InsertBefore(cursor, il.Create(OpCodes.Call, GetLuaMethodInvoker(target, false, false)));
            il.InsertBefore(cursor, il.Create(OpCodes.Ret));
        }
    }
 public InjectAttribute(LifeTypes lifetype = LifeTypes.Single, InjectType injectType = InjectType.AsInterface)
 {
     _lifeType = lifetype;
     _injectType = injectType;
 }
示例#16
0
 public TypeItemObject(Type serviceType, object implementationTypeInstance, object[] parameters, ServiceLifetime serviceLifetime, InjectType injectMode)
     : this(serviceType, implementationTypeInstance.GetType(), parameters, serviceLifetime, injectMode)
 {
     _implementationTypeInstance = implementationTypeInstance;
 }
示例#17
0
		public virtual void Inject(InjectType type)
		{
			try
			{
				using (var frm = new InjectForm())
				{
					if (frm.ShowDialog(type) == DialogResult.OK)
						ItemInjected(this, EventArgs.Empty);
				}
			}
			catch (AssemblyResolutionException arException)
			{
				ShowMessage(string.Format("Unable to resolve assembly {0}, please load it prior to injection.", arException.AssemblyReference.Name));
			}
		}
示例#18
0
 public InjectAttribute(InjectType injectMode)
 {
     InjectMode = injectMode;
 }
示例#19
0
        public static InjectMethod <TTarget, TSource> GetInjectMethod <TTarget, TSource>(InjectType injectType)
        {
            Type   typeTarget = typeof(TTarget);
            Type   typeSource = typeof(TSource);
            string key        = typeTarget.Name + typeSource.Name;
            InjectMethod <TTarget, TSource> injector = _injectors[key] as InjectMethod <TTarget, TSource>;

            if (injector != null)
            {
                return(injector);
            }
            DynamicMethod method  = new DynamicMethod(key, null, new Type[] { typeTarget, typeSource }, true);
            var           il      = method.GetILGenerator();
            var           tFields = typeTarget.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
            var           sFields = typeSource.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

            foreach (var tField in tFields)
            {
                var sField = sFields.Where(f => f.Name == tField.Name).FirstOrDefault();
                if (sField == null)
                {
                    continue;
                }
                if (tField.FieldType.IsPrimitive || tField.FieldType.IsValueType || tField.FieldType == typeof(string))
                {
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Ldfld, sField);
                    il.Emit(OpCodes.Stfld, tField);
                }
            }
            il.Emit(OpCodes.Ret);
            injector        = (InjectMethod <TTarget, TSource>)method.CreateDelegate(typeof(InjectMethod <TTarget, TSource>));
            _injectors[key] = injector;
            return(injector);
        }
示例#20
0
		public DialogResult ShowDialog(InjectType type)
		{
			TargetType = type;
			OwnerType.Enabled = false;
			OwnerPanel.Enabled = false;
			ItemType.Enabled = false;
			return ShowDialog();
		}
示例#21
0
    static void FillInjectMethod(MethodDefinition target, Action <MethodDefinition, InjectType> fillInjectInfo, InjectType runtimeInjectType)
    {
        if (runtimeInjectType == InjectType.None)
        {
            return;
        }

        MethodBody  targetBody = target.Body;
        ILProcessor il         = targetBody.GetILProcessor();

        cursor = GetMethodNextInsertPosition(target, null, runtimeInjectType.HasFlag(InjectType.After));

        while (cursor != null)
        {
            bool        bAfterInject = runtimeInjectType == InjectType.After;
            Instruction startPos     = il.Create(OpCodes.Ldloc, flagDef);
            if (bAfterInject)
            {
                /// Replace instruction with references reserved
                Instruction endPos       = il.Create(OpCodes.Ret);
                int         replaceIndex = targetBody.Instructions.IndexOf(cursor);
                cursor.OpCode  = startPos.OpCode;
                cursor.Operand = startPos.Operand;
                il.InsertAfter(targetBody.Instructions[replaceIndex], endPos);
                cursor = targetBody.Instructions[replaceIndex + 1];
            }
            else
            {
                il.InsertBefore(cursor, startPos);
            }
            il.InsertBefore(cursor, il.Create(ldcI4s[(int)InjectType.After / 2]));
            il.InsertBefore(cursor, il.Create(bAfterInject ? OpCodes.Bne_Un : OpCodes.Ble_Un, cursor));

            fillInjectInfo(target, runtimeInjectType);
            cursor = GetMethodNextInsertPosition(target, cursor, runtimeInjectType.HasFlag(InjectType.After));
        }
    }
示例#22
0
 /// <summary>
 /// 注册
 /// </summary>
 /// <typeparam name="ServiceType"></typeparam>
 /// <param name="implementationTypeInstance"></param>
 /// <param name="serviceLifetime"></param>
 /// <returns></returns>
 public static IIoc AddType <ServiceType>(this IIoc ioc, ServiceType implementationTypeInstance, ServiceLifetime serviceLifetime, InjectType injectMode, object[] parameters = null)
     where ServiceType : class
 {
     ioc.AddType(typeof(ServiceType), implementationTypeInstance, serviceLifetime, injectMode, parameters);
     return(ioc);
 }
示例#23
0
        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="serviceType"></param>
        /// <param name="implementationTypeInstance"></param>
        /// <param name="serviceLifetime"></param>
        /// <returns></returns>
        public IIoc AddType(Type serviceType, object implementationTypeInstance, ServiceLifetime serviceLifetime, InjectType injectMode, object[] parameters = null)
        {
            TypeItemObject typeItemObject = new TypeItemObject(serviceType, implementationTypeInstance, parameters, serviceLifetime, injectMode);

            TypeItemObject.TypeItemObjectCollectionObject.Add(typeItemObject);
            return(this);
        }
示例#24
0
		/// <summary>
		/// Inject an item definition into an owner
		/// </summary>
		/// <param name="owner">Owner item</param>
		/// <param name="targettype">Target type definition</param>
		/// <param name="name">name for the newly created item</param>
		/// <param name="extratype">Extra type</param>
		/// <returns>Object definition</returns>
		public static object Inject(object owner, InjectType targettype, string name, object extratype)
		{
			if (owner == null || name == null)
				throw new ArgumentException();

			if (owner is AssemblyDefinition)
			{
				var adef = owner as AssemblyDefinition;
				switch (targettype)
				{
					case InjectType.AssemblyReference:
						return InjectAssemblyNameReference(adef, name);
					case InjectType.Type:
						return InjectTypeDefinition(adef.MainModule, name, adef.MainModule.Import(extratype as TypeReference));
					case InjectType.Class:
						return InjectClassDefinition(adef.MainModule, name, adef.MainModule.Import(extratype as TypeReference));
					case InjectType.Interface:
						return InjectInterfaceDefinition(adef.MainModule, name);
					case InjectType.Struct:
						return InjectStructDefinition(adef.MainModule, name);
					case InjectType.Enum:
						return InjectEnumDefinition(adef.MainModule, name);
					case InjectType.Resource:
						return InjectResource(adef.MainModule, name, (ResourceType) extratype);
				}
			}
			else if (owner is TypeDefinition)
			{
				var tdef = owner as TypeDefinition;

				switch (targettype)
				{
					case InjectType.Type:
						return InjectInnerTypeDefinition(tdef, name, tdef.Module.Import(extratype as TypeReference));
					case InjectType.Class:
						return InjectInnerClassDefinition(tdef, name, tdef.Module.Import(extratype as TypeReference));
					case InjectType.Interface:
						return InjectInnerInterfaceDefinition(tdef, name);
					case InjectType.Struct:
						return InjectInnerStructDefinition(tdef, name);
					case InjectType.Enum:
						return InjectInnerEnumDefinition(tdef, name);
					case InjectType.Constructor:
						return InjectConstructorDefinition(tdef);
					case InjectType.Method:
						return InjectMethodDefinition(tdef, name);
					case InjectType.Property:
						return InjectPropertyDefinition(tdef, name, tdef.Module.Import(extratype as TypeReference));
					case InjectType.Field:
						return InjectFieldDefinition(tdef, name, tdef.Module.Import(extratype as TypeReference));
					case InjectType.Event:
						return InjectEventDefinition(tdef, name, tdef.Module.Import(extratype as TypeReference));
				}
			}

			throw new NotImplementedException();
		}
 public InjectAttribute(InjectType injectType)
     : this(LifeTypes.Single, InjectType.AsSelf)
 {
 }
示例#26
0
        /// <summary>
        /// Inject an item definition into an owner
        /// </summary>
        /// <param name="owner">Owner item</param>
        /// <param name="targettype">Target type definition</param>
        /// <param name="name">name for the newly created item</param>
        /// <param name="extratype">Extra type</param>
        /// <returns>Object definition</returns>
        public static object Inject(object owner, InjectType targettype, string name, object extratype)
        {
            if (owner == null || name == null)
            {
                throw new ArgumentException();
            }

            if (owner is AssemblyDefinition)
            {
                var adef = owner as AssemblyDefinition;
                switch (targettype)
                {
                case InjectType.AssemblyReference:
                    return(InjectAssemblyNameReference(adef, name));

                case InjectType.Type:
                    return(InjectTypeDefinition(adef.MainModule, name, adef.MainModule.Import(extratype as TypeReference)));

                case InjectType.Class:
                    return(InjectClassDefinition(adef.MainModule, name, adef.MainModule.Import(extratype as TypeReference)));

                case InjectType.Interface:
                    return(InjectInterfaceDefinition(adef.MainModule, name));

                case InjectType.Struct:
                    return(InjectStructDefinition(adef.MainModule, name));

                case InjectType.Enum:
                    return(InjectEnumDefinition(adef.MainModule, name));

                case InjectType.Resource:
                    return(InjectResource(adef.MainModule, name, (ResourceType)extratype));
                }
            }
            else if (owner is TypeDefinition)
            {
                var tdef = owner as TypeDefinition;

                switch (targettype)
                {
                case InjectType.Type:
                    return(InjectInnerTypeDefinition(tdef, name, tdef.Module.Import(extratype as TypeReference)));

                case InjectType.Class:
                    return(InjectInnerClassDefinition(tdef, name, tdef.Module.Import(extratype as TypeReference)));

                case InjectType.Interface:
                    return(InjectInnerInterfaceDefinition(tdef, name));

                case InjectType.Struct:
                    return(InjectInnerStructDefinition(tdef, name));

                case InjectType.Enum:
                    return(InjectInnerEnumDefinition(tdef, name));

                case InjectType.Constructor:
                    return(InjectConstructorDefinition(tdef));

                case InjectType.Method:
                    return(InjectMethodDefinition(tdef, name));

                case InjectType.Property:
                    return(InjectPropertyDefinition(tdef, name, tdef.Module.Import(extratype as TypeReference)));

                case InjectType.Field:
                    return(InjectFieldDefinition(tdef, name, tdef.Module.Import(extratype as TypeReference)));

                case InjectType.Event:
                    return(InjectEventDefinition(tdef, name, tdef.Module.Import(extratype as TypeReference)));
                }
            }

            throw new NotImplementedException();
        }
 public InjectAttribute(InjectType injectType)
     : this(LifeTypes.Single, InjectType.AsSelf)
 {
 }
 public InjectAttribute(LifeTypes lifetype = LifeTypes.Single, InjectType injectType = InjectType.AsInterface)
 {
     _lifeType   = lifetype;
     _injectType = injectType;
 }