//如果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; } } } } }
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); }
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); }
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); }
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)); }
public DialogResult ShowDialog(InjectType type) { TargetType = type; OwnerType.Enabled = false; OwnerPanel.Enabled = false; ItemType.Enabled = false; return(ShowDialog()); }
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(); }
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); }
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)); } }
/// <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); }
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; }
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)); } } }
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; } }
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; }
public TypeItemObject(Type serviceType, object implementationTypeInstance, object[] parameters, ServiceLifetime serviceLifetime, InjectType injectMode) : this(serviceType, implementationTypeInstance.GetType(), parameters, serviceLifetime, injectMode) { _implementationTypeInstance = implementationTypeInstance; }
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)); } }
public InjectAttribute(InjectType injectMode) { InjectMode = injectMode; }
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); }
public DialogResult ShowDialog(InjectType type) { TargetType = type; OwnerType.Enabled = false; OwnerPanel.Enabled = false; ItemType.Enabled = false; return ShowDialog(); }
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)); } }
/// <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); }
/// <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); }
/// <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) { }
/// <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(); }