private static bool CheckCacheTypeMethods(BaseModuleWeaver weaver, TypeDefinition cacheType) { weaver.LogInfo(string.Format("Checking CacheType methods ({0}, {1}, {2}).", CacheTypeContainsMethodName, CacheTypeStoreMethodName, CacheTypeRetrieveMethodName)); if (CacheTypeGetContainsMethod(cacheType, CacheTypeContainsMethodName) == null) { weaver.LogWarning(string.Format("Method {0} missing in {1}.", CacheTypeContainsMethodName, cacheType.FullName)); return(false); } if (CacheTypeGetStoreMethod(cacheType, CacheTypeStoreMethodName) == null) { weaver.LogWarning(string.Format("Method {0} missing in {1}.", CacheTypeStoreMethodName, cacheType.FullName)); return(false); } if (CacheTypeGetRetrieveMethod(cacheType, CacheTypeRetrieveMethodName) == null) { weaver.LogWarning(string.Format("Method {0} missing in {1}.", CacheTypeRetrieveMethodName, cacheType.FullName)); return(false); } weaver.LogInfo(string.Format("CacheInterface methods found.")); return(true); }
public static bool IsMethodValidForWeaving(BaseModuleWeaver weaver, MethodDefinition propertyGet, MethodDefinition methodDefinition) { //only non-static method need a getter if (propertyGet == null && !methodDefinition.IsStatic) { weaver.LogWarning(string.Format("Class {0} does not contain or inherit Getter {1}. Skip weaving of method {2}.", methodDefinition.DeclaringType.Name, CacheGetterName, methodDefinition.Name)); return(false); } //not need anymore //if (methodDefinition.IsStatic && !propertyGet.IsStatic) //{ // weaver.LogWarning(string.Format("Method {2} of Class {0} is static, Getter {1} is not. Skip weaving of method {2}.", // methodDefinition.DeclaringType.Name, CacheGetterName, methodDefinition.Name)); // return false; //} if (!methodDefinition.IsStatic && !CheckCacheTypeMethods(weaver, propertyGet.ReturnType.Resolve())) { weaver.LogWarning( string.Format( "ReturnType {0} of Getter {1} of Class {2} does not implement all methods. Skip weaving of method {3}.", propertyGet.ReturnType.Name, CacheGetterName, methodDefinition.DeclaringType.Name, methodDefinition.Name)); return(false); } return(true); }
private static MethodReference GetMemberInfoNamePropertyGetMethod(BaseModuleWeaver weaver) { TypeDefinition memberInfoType = weaver.FindType(typeof(MemberInfo).FullName); PropertyDefinition memberInfoNameProperty = memberInfoType.Properties.Single(property => property.Name == nameof(MemberInfo.Name)); return(weaver.ModuleDefinition.ImportReference(memberInfoNameProperty.GetMethod)); }
public WeaverHolder( BaseModuleWeaver instance, WeaverEntry config) { Instance = instance; Config = config; }
public bool Validate(BaseModuleWeaver weaver) { if (!Effects.Any()) { weaver.LogWarning($"Type {Host.FullName} has defined as an aspect, but lacks any effect."); } if (Host.HasGenericParameters) { weaver.LogError($"Aspect {Host.FullName} should not have generic parameters."); return(false); } if (Host.IsAbstract) { weaver.LogError($"Aspect {Host.FullName} cannot be static nor abstract."); return(false); } if (GetFactoryMethod() == null) { if (Factory != null) { weaver.LogError($"Type {Factory.FullName} should have 'public static object GetInstance(Type)' method in order to be aspect factory."); } else { weaver.LogError($"Aspect {Host.FullName} has no parameterless public constructor nor valid factory."); } return(false); } return(Effects.All(e => e.Validate(this, weaver))); }
public static void Weave(BaseModuleWeaver weaver, IEnumerable <Tuple <MethodDefinition, CustomAttribute> > methods) { foreach (Tuple <MethodDefinition, CustomAttribute> methodDefinition in methods) { WeaveMethod(weaver, methodDefinition.Item1, methodDefinition.Item2); } }
public static void Weave(BaseModuleWeaver weaver, IEnumerable <Tuple <PropertyDefinition, CustomAttribute> > properties) { foreach (Tuple <PropertyDefinition, CustomAttribute> propertyTuple in properties) { PropertyDefinition property = propertyTuple.Item1; CustomAttribute attribute = propertyTuple.Item2; // Get-Only Property, weave like normal methods if (property.SetMethod == null) { WeaveMethod(weaver, property.GetMethod, attribute); } else { MethodDefinition propertyGet = GetCacheGetter(property.SetMethod); if (!IsPropertySetterValidForWeaving(weaver, propertyGet, property.SetMethod)) { continue; } weaver.LogInfo(string.Format("Weaving property {0}::{1}.", property.DeclaringType.Name, property.Name)); WeaveMethod(weaver, property.GetMethod, attribute, propertyGet); WeavePropertySetter(weaver, property.SetMethod, propertyGet); } } }
public void FindReferences(BaseModuleWeaver moduleWeaver) { var moduleDefinition = moduleWeaver.ModuleDefinition; SystemType = moduleWeaver.FindTypeDefinition("System.Type"); DebuggerBrowsableStateType = moduleWeaver.FindTypeDefinition("System.Diagnostics.DebuggerBrowsableState"); var listType = moduleWeaver.FindTypeDefinition("System.Collections.Generic.List`1"); ListCtor = moduleDefinition.ImportReference(listType.Methods.First(m => m.IsConstructor && m.Parameters.Count == 1 && m.Parameters[0].ParameterType.Name.StartsWith("IEnumerable"))); ListToArray = moduleDefinition.ImportReference(listType.Methods.First(m => m.Name == "ToArray")); var debuggerBrowsableAttribute = moduleWeaver.FindTypeDefinition("System.Diagnostics.DebuggerBrowsableAttribute"); DebuggerBrowsableAttributeCtor = moduleDefinition.ImportReference(debuggerBrowsableAttribute.Methods.First(x => x.IsConstructor)); var debuggerDisplayAttribute = moduleWeaver.FindTypeDefinition("System.Diagnostics.DebuggerDisplayAttribute"); DebuggerDisplayAttributeCtor = moduleDefinition.ImportReference(debuggerDisplayAttribute.Methods.First(x => x.IsConstructor)); var debuggerTypeProxyAttribute = moduleWeaver.FindTypeDefinition("System.Diagnostics.DebuggerTypeProxyAttribute"); DebuggerTypeProxyAttributeCtor = moduleDefinition.ImportReference(debuggerTypeProxyAttribute.Methods.First(x => x.IsConstructor && x.Parameters[0].ParameterType.FullName == "System.Type")); var compilerGeneratedAttribute = moduleWeaver.FindTypeDefinition("System.Runtime.CompilerServices.CompilerGeneratedAttribute"); CompilerGeneratedAttributeCtor = moduleDefinition.ImportReference(compilerGeneratedAttribute.Methods.First(x => x.IsConstructor)); StringFormat = moduleDefinition.ImportReference(moduleWeaver.FindTypeDefinition("System.String").Methods .First(m => m.Name == "Format" && m.Parameters.Count == 2 && m.Parameters[0].ParameterType.FullName == "System.String" && m.Parameters[1].ParameterType.FullName == "System.Object[]")); }
public virtual void SetProperties(WeaverEntry weaverEntry, BaseModuleWeaver weaverInstance) { if (weaverEntry.Element != null) { var weaverElement = XElement.Parse(weaverEntry.Element); weaverInstance.Config = weaverElement; } weaverInstance.ModuleDefinition = ModuleDefinition; weaverInstance.AssemblyFilePath = AssemblyFilePath; weaverInstance.AddinDirectoryPath = Path.GetDirectoryName(weaverEntry.AssemblyPath); weaverInstance.References = References; weaverInstance.ReferenceCopyLocalPaths = ReferenceCopyLocalPaths; weaverInstance.SolutionDirectoryPath = SolutionDirectoryPath; weaverInstance.ProjectDirectoryPath = ProjectDirectoryPath; weaverInstance.DocumentationFilePath = DocumentationFilePath; weaverInstance.LogDebug = message => Logger.LogDebug(" " + message); weaverInstance.LogInfo = message => Logger.LogInfo(" " + message); weaverInstance.LogMessage = (message, importance) => Logger.LogMessage(" " + message, (int)importance); weaverInstance.LogWarning = Logger.LogWarning; weaverInstance.LogWarningPoint = LogWarningPoint; weaverInstance.LogError = Logger.LogError; weaverInstance.LogErrorPoint = LogErrorPoint; weaverInstance.DefineConstants = DefineConstants; weaverInstance.FindType = TypeCache.FindType; weaverInstance.TryFindType = TypeCache.TryFindType; weaverInstance.ResolveAssembly = assemblyName => assemblyResolver.Resolve(assemblyName); }
private static MethodReference GetHasValueGetMethod(BaseModuleWeaver weaver) { TypeDefinition nullableType = weaver.FindType(typeof(Nullable <>).FullName); PropertyDefinition hasValueProperty = nullableType.Properties.Single(property => property.Name == nameof(Nullable <int> .HasValue)); return(weaver.ModuleDefinition.ImportReference(hasValueProperty.GetMethod)); }
public static void CleanReferences(ModuleDefinition module, BaseModuleWeaver weaver, Action <string> log) { if (!weaver.ShouldCleanReference) { return; } var weaverLibName = weaver.GetType().Assembly.GetName().Name.ReplaceCaseless(".Fody", ""); log($"\tRemoving reference to '{weaverLibName}'."); var referenceToRemove = module.AssemblyReferences.FirstOrDefault(x => x.Name == weaverLibName); if (referenceToRemove != null) { module.AssemblyReferences.Remove(referenceToRemove); } var copyLocalFilesToRemove = new HashSet <string>(StringComparer.OrdinalIgnoreCase) { weaverLibName + ".dll", weaverLibName + ".xml", weaverLibName + ".pdb", weaverLibName + ".mdb" // TODO: Remove this when mdb becomes redundant }; weaver.ReferenceCopyLocalPaths.RemoveAll(refPath => copyLocalFilesToRemove.Contains(Path.GetFileName(refPath))); }
public static void LoadReferences(BaseModuleWeaver weaver) { _weaver = weaver; DebugWriteLineMethod = weaver.FindType("System.Diagnostics.Debug").Method("WriteLine"); StringFormatMethod = weaver.FindType("System.String").Method("Format", new string[] { "String", "Object[]" }); SystemTypeGetTypeFromHandleMethod = weaver.FindType("Type").Method("GetTypeFromHandle"); var typeDictionary = weaver.FindType("Dictionary`2"); var genericArg = new TypeReference[] { weaver.ModuleDefinition.TypeSystem.String, weaver.ModuleDefinition.TypeSystem.Object }; var genericDic = typeDictionary.MakeGenericInstanceType(genericArg); DictionaryConstructor = genericDic.Resolve().GetConstructors().FirstOrDefault(); DictionaryAddMethod = genericDic.Resolve().Method("Add"); //make ctor method has generic parms, cause Resolve() will remove generic parameters all DictionaryConstructor.DeclaringType = DictionaryConstructor.DeclaringType.MakeGenericInstanceType(genericArg); DictionaryAddMethod.DeclaringType = DictionaryAddMethod.DeclaringType.MakeGenericInstanceType(genericArg); #if DEBUG CacheAssembly = weaver.ResolveAssembly("Cache"); #else //load Cache reference var references = SplitUpReferences(weaver); AssemblyResolver = new AssemblyResolver(references); CacheAssembly = AssemblyResolver.Resolve("Cache"); #endif }
public ReferencesProvider(ModuleDefinition moduleDefinition, BaseModuleWeaver baseModuleWeaver) { _moduleDefinition = moduleDefinition ?? throw new ArgumentNullException(nameof(moduleDefinition)); _baseModuleWeaver = baseModuleWeaver ?? throw new ArgumentNullException(nameof(baseModuleWeaver)); FindRequiredTypesAndMethods(); }
static TypeCache CacheTypes(BaseModuleWeaver weaver, Func <string, AssemblyDefinition> resolver) { var typeCache = new TypeCache(resolver); typeCache.BuildAssembliesToScan(weaver); return(typeCache); }
public AdviceAfterProcess(BaseModuleWeaver weaver, MethodDefinition target, AspectDefinition aspect, AfterAdviceEffect effect) : base(weaver, target, effect, aspect) { if (_target.ReturnType.FullName != WellKnownTypes.Void && effect.Arguments.Any(a => a.Source == Broker.Advice.Argument.Source.ReturnValue)) { _retvar = GetOrCreateRetVar(); } }
protected InjectionImplementor(TypeDefinition typeDefinition, IMemberDefinition[] memberDefinitions, ModuleDefinition moduleDefinition, ReferencesProvider referencesProvider, BaseModuleWeaver baseModuleWeaver) { _baseModuleWeaver = baseModuleWeaver ?? throw new ArgumentNullException(nameof(baseModuleWeaver)); _referencesProvider = referencesProvider ?? throw new ArgumentNullException(nameof(referencesProvider)); _moduleDefinition = moduleDefinition ?? throw new ArgumentNullException(nameof(moduleDefinition)); _memberDefinitions = memberDefinitions ?? throw new ArgumentNullException(nameof(memberDefinitions)); _typeDefinition = typeDefinition ?? throw new ArgumentNullException(nameof(typeDefinition)); }
public MethodSubscriptionImplementor(TypeDefinition typeDefinition, MethodDefinition[] methodsToSubscribe, ModuleDefinition moduleDefinition, ReferencesProvider referencesProvider, BaseModuleWeaver baseModuleWeaver) { _baseModuleWeaver = baseModuleWeaver; _referencesProvider = referencesProvider ?? throw new ArgumentNullException(nameof(referencesProvider)); _moduleDefinition = moduleDefinition ?? throw new ArgumentNullException(nameof(moduleDefinition)); _methodsToSubscribe = methodsToSubscribe ?? throw new ArgumentNullException(nameof(methodsToSubscribe)); _typeDefinition = typeDefinition ?? throw new ArgumentNullException(nameof(typeDefinition)); }
private static MethodReference GetIndexerGetMethod(BaseModuleWeaver weaver) { TypeDefinition stringType = weaver.FindType(typeof(string).FullName); PropertyDefinition indexer = stringType.Properties.Single(property => property.Parameters.Count == 1 && property.Parameters[0].ParameterType.FullName == typeof(int).FullName); return(weaver.ModuleDefinition.ImportReference(indexer.GetMethod)); }
public AdviceWeaveProcessBase(BaseModuleWeaver weaver, MethodDefinition target, TEffect effect, AspectDefinition aspect) { _weaver = weaver; _target = target; _effect = effect; _aspect = aspect; _ts = target.Module.GetTypeSystem(); }
private static MethodReference GetToStringMethod(BaseModuleWeaver weaver) { TypeDefinition objectType = weaver.FindType(typeof(object).FullName); MethodDefinition objectToStringMethod = objectType.Methods.Single(method => method.IsStatic == false && method.Name == nameof(object.ToString) && method.Parameters.Count == 0); return(weaver.ModuleDefinition.ImportReference(objectToStringMethod)); }
public InjectorCallReplacer(TypeDefinition definition, string methodNameToCall, MethodDefinition methodToRemove, ActivityGetViewMethodImplementor activityGetViewMethodImplementor, BaseModuleWeaver baseModuleWeaver) { _definition = definition; _methodNameToCall = methodNameToCall; _methodToRemove = methodToRemove; _activityGetViewMethodImplementor = activityGetViewMethodImplementor; _baseModuleWeaver = baseModuleWeaver ?? throw new ArgumentNullException(nameof(baseModuleWeaver)); _methodIsParameterless = !methodToRemove.HasParameters; }
public static PropertyDefinition InjectProperty(BaseModuleWeaver weaver, MethodDefinition methodDefinition) { //Import Reference TypeDefinition mdlClass = methodDefinition.DeclaringType; var refModule = ReferenceFinder.CacheAssembly.MainModule; var refInterface = refModule.GetType("Cache.ICacheProvider"); //define the field we store the value in FieldDefinition field = new FieldDefinition( "<Cache>k__BackingField", FieldAttributes.Private | FieldAttributes.Static, mdlClass.Module.ImportReference(refInterface)); mdlClass.Fields.Add(field); //Create the get method MethodDefinition get = new MethodDefinition("get_Cache", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Static, mdlClass.Module.ImportReference(refInterface)); ILProcessor processorGet = get.Body.GetILProcessor(); get.Body.Instructions.Add(processorGet.Create(OpCodes.Ldsfld, field)); get.Body.Instructions.Add(processorGet.Create(OpCodes.Ret)); get.Body.InitLocals = true; get.SemanticsAttributes = MethodSemanticsAttributes.Getter; mdlClass.Methods.Add(get); //Create the set method MethodDefinition set = new MethodDefinition("set_Cache", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Static, mdlClass.Module.TypeSystem.Void); ILProcessor processorSet = set.Body.GetILProcessor(); set.Body.Instructions.Add(processorSet.Create(OpCodes.Ldarg_0)); set.Body.Instructions.Add(processorSet.Create(OpCodes.Stsfld, field)); set.Body.Instructions.Add(processorSet.Create(OpCodes.Ret)); set.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, mdlClass.Module.ImportReference(refInterface))); set.SemanticsAttributes = MethodSemanticsAttributes.Setter; mdlClass.Methods.Add(set); //create the property PropertyDefinition propertyDefinition = new PropertyDefinition( "Cache", PropertyAttributes.None, mdlClass.Module.ImportReference(refInterface)) { GetMethod = get, SetMethod = set }; //add the property to the type. mdlClass.Properties.Add(propertyDefinition); return(propertyDefinition); }
private static MethodReference GetArgumentExceptionWithMessageConstructor(BaseModuleWeaver weaver) { TypeDefinition argumentExceptionType = weaver.FindType(typeof(ArgumentException).FullName); MethodDefinition argumentExceptionWithMessageConstructor = argumentExceptionType.Methods.Single(method => method.IsConstructor && method.Parameters.Count == 2 && method.Parameters[0].ParameterType.FullName == typeof(string).FullName && method.Parameters[1].ParameterType.FullName == typeof(string).FullName); return(weaver.ModuleDefinition.ImportReference(argumentExceptionWithMessageConstructor)); }
private static MethodReference GetGetTypeFromHandleMethod(BaseModuleWeaver weaver) { TypeDefinition typeType = weaver.FindType(typeof(Type).FullName); MethodDefinition getTypeFromHandleMethod = typeType.Methods.Single(method => method.IsStatic && method.Name == nameof(Type.GetTypeFromHandle) && method.Parameters.Count == 1 && method.Parameters[0].ParameterType.FullName == typeof(RuntimeTypeHandle).FullName); return(weaver.ModuleDefinition.ImportReference(getTypeFromHandleMethod)); }
/// <summary> /// Initializes a new instance of the <see cref="ActionWeaver"/> class. /// </summary> /// <param name="parentWeaver">A reference to the Parent Cortex.Net weaver.</param> /// <param name="processorQueue">The queue to add ILProcessor actions to.</param> /// <param name="resolvedTypes">The resolved types necessary by this weaver.</param> /// <exception cref="ArgumentNullException">When any of the arguments is null.</exception> public ActionWeaver(BaseModuleWeaver parentWeaver, ISharedStateAssignmentILProcessorQueue processorQueue, IDictionary <string, TypeReference> resolvedTypes) { if (resolvedTypes is null) { throw new ArgumentNullException(nameof(resolvedTypes)); } this.parentWeaver = parentWeaver ?? throw new ArgumentNullException(nameof(parentWeaver)); this.processorQueue = processorQueue ?? throw new ArgumentNullException(nameof(processorQueue)); this.actionAttributeReference = resolvedTypes["Cortex.Net.Api.ActionAttribute"]; this.actionExtensionsReference = resolvedTypes["Cortex.Net.Api.ActionExtensions"]; }
/// <summary> /// Initializes a new instance of the <see cref="BlazorObserverWeaver"/> class. /// </summary> /// <param name="parentWeaver">The parent weaver of this weaver.</param> /// <param name="processorQueue">The processor queue to add delegates to, to be executed on ISharedState property assignment.</param> /// <param name="resolvedTypes">The resolved types necessary by this weaver.</param> public BlazorObserverWeaver(BaseModuleWeaver parentWeaver, ISharedStateAssignmentILProcessorQueue processorQueue, IDictionary <string, TypeReference> resolvedTypes) { if (resolvedTypes is null) { throw new ArgumentNullException(nameof(resolvedTypes)); } this.parentWeaver = parentWeaver ?? throw new ArgumentNullException(nameof(parentWeaver)); this.processorQueue = processorQueue ?? throw new ArgumentNullException(nameof(processorQueue)); this.observerAttributeReference = resolvedTypes["Cortex.Net.Blazor.ObserverAttribute"]; this.observerObjectReference = resolvedTypes["Cortex.Net.Blazor.ObserverObject"]; }
private static Instruction SetCacheKeyLocalVariable(BaseModuleWeaver weaver, Instruction current, MethodDefinition methodDefinition, ILProcessor processor, int cacheKeyIndex, int objectArrayIndex) { if (methodDefinition.IsSetter || methodDefinition.IsGetter) { return(current.AppendStloc(processor, cacheKeyIndex)); } else { // Create object[] for string.format int parameterCount = methodDefinition.Parameters.Count + methodDefinition.GenericParameters.Count; current = current .AppendLdcI4(processor, parameterCount) .Append(processor.Create(OpCodes.Newarr, weaver.ModuleDefinition.TypeSystem.Object), processor) .AppendStloc(processor, objectArrayIndex); // Set object[] values for (int i = 0; i < methodDefinition.GenericParameters.Count; i++) { current = current .AppendLdloc(processor, objectArrayIndex) .AppendLdcI4(processor, i) .Append(processor.Create(OpCodes.Ldtoken, methodDefinition.GenericParameters[i]), processor) .Append(processor.Create(OpCodes.Call, methodDefinition.Module.ImportMethod(ReferenceFinder.SystemTypeGetTypeFromHandleMethod)), processor) .Append(processor.Create(OpCodes.Stelem_Ref), processor); } for (int i = 0; i < methodDefinition.Parameters.Count; i++) { current = current .AppendLdloc(processor, objectArrayIndex) .AppendLdcI4(processor, methodDefinition.GenericParameters.Count + i) .AppendLdarg(processor, !methodDefinition.IsStatic ? i + 1 : i) .AppendBoxIfNecessary(processor, methodDefinition.Parameters[i].ParameterType) .Append(processor.Create(OpCodes.Stelem_Ref), processor); } // Call string.format var ins = processor.Create(OpCodes.Call, methodDefinition.Module.ImportMethod(ReferenceFinder.StringFormatMethod)); return(current .AppendLdloc(processor, objectArrayIndex) .Append(ins, processor) .AppendStloc(processor, cacheKeyIndex)); } }
public AopModuleWeaver( IAspectReader aspectExtractor, IInjectionReader injectionCollector, IAspectWeaver aspectWeaver, IEnumerable <IEffectWeaver> effectWeavers, BaseModuleWeaver weaver) { _aspectExtractor = aspectExtractor; _injectionCollector = injectionCollector; _aspectWeaver = aspectWeaver; _effectWeavers = effectWeavers; _weaver = weaver; }
/// <summary> /// Initializes a new instance of the <see cref="ObservableObjectWeaverBase"/> class. /// </summary> /// <param name="parentWeaver">The parent weaver.</param> /// <param name="processorQueue">The processor queue to add delegates to.</param> /// <param name="resolvedTypes">The resolved types necessary by this weaver.</param> protected ObservableObjectWeaverBase(BaseModuleWeaver parentWeaver, ISharedStateAssignmentILProcessorQueue processorQueue, IDictionary <string, TypeReference> resolvedTypes) { if (resolvedTypes is null) { throw new ArgumentNullException(nameof(resolvedTypes)); } this.ParentWeaver = parentWeaver ?? throw new ArgumentNullException(nameof(parentWeaver)); this.ProcessorQueue = processorQueue ?? throw new ArgumentNullException(nameof(processorQueue)); this.observableObjectReference = resolvedTypes["Cortex.Net.Types.ObservableObject"]; this.actionExtensionsReference = resolvedTypes["Cortex.Net.Core.ActionExtensions"]; }
private static MethodReference GetConcatThreeStringsMethod(BaseModuleWeaver weaver) { TypeDefinition stringType = weaver.FindType(typeof(string).FullName); MethodDefinition concatThreeStringsMethod = stringType.Methods.Single(method => method.IsStatic && method.Name == nameof(string.Concat) && method.Parameters.Count == 3 && method.Parameters[0].ParameterType.FullName == typeof(string).FullName && method.Parameters[1].ParameterType.FullName == typeof(string).FullName && method.Parameters[2].ParameterType.FullName == typeof(string).FullName); return(weaver.ModuleDefinition.ImportReference(concatThreeStringsMethod)); }