Skip to content

Commit be41c02

Browse files
committed
Fixed #2, fixed method injection of methods with generic parameters
1 parent be1f165 commit be41c02

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

Mono.Cecil.Inject/InjectionDefinition.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,13 @@ Injection has {injectMethod.Parameters.Count
162162
if (hFlags.PassParameters)
163163
{
164164
Assert(
165-
injectMethod.HasGenericParameters == injectTarget.HasGenericParameters,
165+
injectMethod.HasGenericParameters && injectTarget.Parameters.Any(p => p.ParameterType.IsGenericParameter),
166166
"The injection and target methods have mismatching specification of generic parameters!");
167167

168168
Assert(
169169
!injectMethod.HasGenericParameters
170-
|| injectMethod.GenericParameters.Count <= injectTarget.GenericParameters.Count,
171-
"The injection and target methods have a mismatching number of generic parameters! The injection method must have less or the same number of generic paramters as the target!");
170+
|| injectMethod.GenericParameters.Count <= injectTarget.GenericParameters.Count + injectTarget.DeclaringType.GenericParameters.Count,
171+
"The injection and target methods have a mismatching number of generic parameters! The injection method must have less or the same number of generic parameters as the target!");
172172

173173
Assert(
174174
!hFlags.PassParametersByRef
@@ -293,6 +293,23 @@ public void Inject(Instruction startCode, int token = 0, InjectDirection directi
293293

294294
MethodReference hookRef = InjectTarget.Module.Import(InjectMethod);
295295

296+
// If the hook is generic but not instantiated fully, attempt to fill in the generic arguments with the ones specified in the target method/class
297+
if (hookRef.HasGenericParameters && (!hookRef.IsGenericInstance || hookRef.IsGenericInstance && ((GenericInstanceMethod)hookRef).GenericArguments.Count < hookRef.GenericParameters.Count))
298+
{
299+
GenericInstanceMethod genericInjectMethod = new GenericInstanceMethod(hookRef);
300+
foreach (GenericParameter genericParameter in InjectMethod.GenericParameters)
301+
{
302+
List<GenericParameter> @params = new List<GenericParameter>();
303+
@params.AddRange(InjectTarget.GenericParameters);
304+
@params.AddRange(InjectTarget.DeclaringType.GenericParameters);
305+
GenericParameter param = @params.FirstOrDefault(p => p.Name == genericParameter.Name);
306+
if (param == null)
307+
throw new Exception("Could not find a suitable type to bind to the generic injection method. Try to manually instantiate the generic injection method before injecting.");
308+
genericInjectMethod.GenericArguments.Add(param);
309+
}
310+
hookRef = genericInjectMethod;
311+
}
312+
296313
MethodBody targetBody = InjectTarget.Body;
297314
ILProcessor il = targetBody.GetILProcessor();
298315
int startIndex = targetBody.Instructions.IndexOf(startCode);

Mono.Cecil.Inject/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@
3535
// by using the '*' as shown below:
3636
// [assembly: AssemblyVersion("1.0.*")]
3737

38-
[assembly: AssemblyVersion("1.2.1.0")]
39-
[assembly: AssemblyFileVersion("1.2.1.0")]
38+
[assembly: AssemblyVersion("1.2.2.0")]
39+
[assembly: AssemblyFileVersion("1.2.2.0")]

0 commit comments

Comments
 (0)