protected override List <MethodDefinition> GetFilteredInjecteeMethods( AssemblyDefinitionCachedData assemblyDefinitionCachedData, List <IgnoredMemberReference> ignoredMemberReferences ) { List <MethodDefinition> filteredInjecteeMethods = base.GetFilteredInjecteeMethods(assemblyDefinitionCachedData, ignoredMemberReferences); filteredInjecteeMethods = filteredInjecteeMethods .Where(method => _injecteeMethodNames.Contains(method.GetFullSimpleName())) .ToList(); return(filteredInjecteeMethods); }
private Dictionary <AssemblyDefinition, List <ResolvedInjectedMethod> > GetInjectedMethods() { var injectedAssemblyToMethodsMap = new Dictionary <AssemblyDefinition, List <ResolvedInjectedMethod> >(); foreach (InjectedMethod sourceInjectedMethod in _injectionConfiguration.InjectedMethods) { AssemblyDefinitionCachedData assemblyDefinitionCachedData = GetAssemblyDefinitionCachedData(sourceInjectedMethod.AssemblyPath, _compoundAssemblyResolver); MethodDefinition[] matchingMethodDefinitions = assemblyDefinitionCachedData .AllMethods .Where(methodDefinition => methodDefinition.GetFullSimpleName() == sourceInjectedMethod.MethodFullName) .ToArray(); if (matchingMethodDefinitions.Length == 0) { throw new MethodInlineInjectorException($"No matching methods found for {sourceInjectedMethod.MethodFullName}"); } if (matchingMethodDefinitions.Length > 2) { throw new MethodInlineInjectorException($"More than 1 matching method found for {sourceInjectedMethod.MethodFullName}"); } if (!injectedAssemblyToMethodsMap.TryGetValue( assemblyDefinitionCachedData.AssemblyDefinition, out List <ResolvedInjectedMethod> methodDefinitions )) { methodDefinitions = new List <ResolvedInjectedMethod>(); injectedAssemblyToMethodsMap.Add(assemblyDefinitionCachedData.AssemblyDefinition, methodDefinitions); } MethodDefinition matchedMethodDefinition = matchingMethodDefinitions[0]; ValidateInjectedMethod(matchedMethodDefinition); methodDefinitions.Add( new ResolvedInjectedMethod( matchedMethodDefinition, sourceInjectedMethod.InjectionPosition ) ); } return(injectedAssemblyToMethodsMap); }
private AssemblyDefinitionCachedData GetAssemblyDefinitionCachedData( string assemblyPath, BaseAssemblyResolver assemblyResolver) { assemblyPath = Path.GetFullPath(assemblyPath); if (!_assemblyPathToAssemblyMap.TryGetValue(assemblyPath, out AssemblyDefinitionCachedData assemblyDefinitionData)) { Log.DebugFormat("Loading assembly at path '{0}'", assemblyPath); AssemblyDefinition assemblyDefinition = LoadAssemblyDefinition(assemblyPath, assemblyResolver); assemblyDefinitionData = new AssemblyDefinitionCachedData(assemblyDefinition); Log.DebugFormat( "Loaded assembly at path '{0}': {1} types, {2} methods", assemblyPath, assemblyDefinitionData.AllTypes.Count, assemblyDefinitionData.AllMethods.Count ); _assemblyPathToAssemblyMap.Add(assemblyPath, assemblyDefinitionData); } return(assemblyDefinitionData); }
protected virtual List <MethodDefinition> GetFilteredInjecteeMethods( AssemblyDefinitionCachedData assemblyDefinitionCachedData, List <IgnoredMemberReference> ignoredMemberReferences) { Dictionary <string, Regex> regexCache = new Dictionary <string, Regex>(); Log.DebugFormat("Number of types before filtering: {0}", assemblyDefinitionCachedData.AllTypes.Count); TypeDefinition[] types = assemblyDefinitionCachedData .AllTypes .Where(TestType) .ToArray(); Log.DebugFormat("Number of types after filtering: {0}", types.Length); List <MethodDefinition> injecteeMethods = types .SelectMany(GetTestedMethodsFromType) .Where(ValidateInjecteeMethod) .ToList(); Log.DebugFormat("Number of methods after filtering: {0}", injecteeMethods.Count); return(injecteeMethods); Regex GetFilterRegex(IgnoredMemberReference ignoredMemberReference) { if (!regexCache.TryGetValue(ignoredMemberReference.Filter, out Regex filterRegex)) { filterRegex = new Regex(ignoredMemberReference.Filter, RegexOptions.Compiled); regexCache[ignoredMemberReference.Filter] = filterRegex; } return(filterRegex); } bool TestString(IgnoredMemberReference ignoredMemberReference, string fullName) { if (ignoredMemberReference.IsRegex) { if (GetFilterRegex(ignoredMemberReference).IsMatch(fullName)) { return(false); } } else { if (fullName.Contains(ignoredMemberReference.Filter)) { return(false); } } return(true); } bool TestType(TypeDefinition type) { foreach (IgnoredMemberReference ignoredMemberReference in ignoredMemberReferences) { if (!ignoredMemberReference.FilterFlags.HasFlag(IgnoredMemberReferenceFlags.SkipTypes)) { continue; } if (!TestTypeIgnored(type, ignoredMemberReference)) { return(false); } } return(true); } bool TestTypeIgnored(TypeDefinition type, IgnoredMemberReference ignoredMemberReference) { while (true) { if (!TestString(ignoredMemberReference, type.FullName)) { Log.DebugFormat("Ignored type '{0}'", type.FullName); return(false); } if (!ignoredMemberReference.MatchAncestors || type.BaseType == null) { break; } type = type.BaseType.GetDefinition(); } return(true); } IEnumerable <MethodDefinition> GetTestedMethodsFromType(TypeDefinition type) { HashSet <MethodDefinition> ignoredMethods = new HashSet <MethodDefinition>(); foreach (PropertyDefinition property in type.Properties) { foreach (IgnoredMemberReference ignoredMemberReference in ignoredMemberReferences) { if (!ignoredMemberReference.FilterFlags.HasFlag(IgnoredMemberReferenceFlags.SkipProperties)) { continue; } if (ProcessPropertyIgnored(property, ignoredMemberReference, ignoredMethods)) { break; } } } foreach (MethodDefinition method in type.Methods) { foreach (IgnoredMemberReference ignoredMemberReference in ignoredMemberReferences) { if (!ignoredMemberReference.FilterFlags.HasFlag(IgnoredMemberReferenceFlags.SkipMethods)) { continue; } if (ProcessMethodIgnored(method, ignoredMemberReference, ignoredMethods)) { break; } } } return(type.Methods.Except(ignoredMethods).Distinct()); } bool ProcessPropertyIgnored(PropertyDefinition property, IgnoredMemberReference ignoredMemberReference, HashSet <MethodDefinition> ignoredMethods) { PropertyDefinition startProperty = property; while (true) { if (!TestString(ignoredMemberReference, property.GetFullSimpleName())) { Log.DebugFormat("Ignored property '{0}'", startProperty.GetFullSimpleName()); if (startProperty.GetMethod != null) { ignoredMethods.Add(startProperty.GetMethod); } if (startProperty.SetMethod != null) { ignoredMethods.Add(startProperty.SetMethod); } return(false); } if (!ignoredMemberReference.MatchAncestors) { break; } PropertyDefinition baseProperty = property.GetBaseProperty(); if (baseProperty == property) { break; } property = baseProperty; } return(true); } bool ProcessMethodIgnored(MethodDefinition method, IgnoredMemberReference ignoredMemberReference, HashSet <MethodDefinition> ignoredMethods) { MethodDefinition startMethod = method; while (true) { if (!TestString(ignoredMemberReference, method.GetFullSimpleName())) { ignoredMethods.Add(startMethod); Log.DebugFormat("Ignored method '{0}'", startMethod.GetFullSimpleName()); return(false); } if (!ignoredMemberReference.MatchAncestors) { break; } MethodDefinition baseMethod = method.GetBaseMethod(); if (baseMethod == method) { break; } method = baseMethod; } return(true); } }
private ResolvedInjecteeAssembly GetInjecteeAssembly(InjecteeAssembly sourceInjecteeAssembly) { List <IgnoredMemberReference> ignoredMemberReferences = new List <IgnoredMemberReference>(); List <AllowedAssemblyReference> allowedAssemblyReferences = new List <AllowedAssemblyReference>(); void LoadIgnoredMemberReferences(IEnumerable <IIgnoredMemberReference> items) { foreach (IIgnoredMemberReference item in items) { if (item is IgnoredMemberReference ignoredMemberReference) { ignoredMemberReferences.Add(ignoredMemberReference); continue; } if (item is IgnoredMemberReferenceInclude ignoredMemberReferenceInclude) { try { Log.DebugFormat("Loading ignored member references list include at '{0}'", ignoredMemberReferenceInclude.Path); string includeXml = File.ReadAllText(ignoredMemberReferenceInclude.Path); IgnoredMemberReferencesIncludeLoader ignoredMemberReferencesIncludeLoader = SimpleXmlSerializationUtility.XmlDeserializeFromString <IgnoredMemberReferencesIncludeLoader>(includeXml); LoadIgnoredMemberReferences(ignoredMemberReferencesIncludeLoader.Items); } catch (Exception e) { Console.WriteLine(e); throw new MethodInlineInjectorException( $"Unable to load ignored member references list include at '{ignoredMemberReferenceInclude.Path}'", e ); } } } } void LoadAllowedAssemblyReferences(IEnumerable <IAllowedAssemblyReference> items) { foreach (IAllowedAssemblyReference item in items) { if (item is AllowedAssemblyReference allowedAssemblyReference) { allowedAssemblyReferences.Add(allowedAssemblyReference); continue; } if (item is AllowedAssemblyReferenceInclude allowedAssemblyReferenceInclude) { Log.DebugFormat("Loading allowed assembly references list include at '{0}'", allowedAssemblyReferenceInclude.Path); try { string includeXml = File.ReadAllText(allowedAssemblyReferenceInclude.Path); AllowedAssemblyReferenceIncludeLoader allowedAssemblyReferencesLoader = SimpleXmlSerializationUtility.XmlDeserializeFromString <AllowedAssemblyReferenceIncludeLoader>(includeXml); LoadAllowedAssemblyReferences(allowedAssemblyReferencesLoader.Items); } catch (Exception e) { throw new MethodInlineInjectorException( $"Unable to load allowed assembly references list include at '{allowedAssemblyReferenceInclude.Path}'", e ); } } } } LoadIgnoredMemberReferences(sourceInjecteeAssembly.IgnoredMemberReferences); LoadAllowedAssemblyReferences(sourceInjecteeAssembly.AllowedAssemblyReferences); List <ResolvedAllowedAssemblyReference> resolvedAllowedAssemblyReferences = allowedAssemblyReferences .Select(item => new ResolvedAllowedAssemblyReference(AssemblyNameReference.Parse(item.Name), item.Path, item.StrictNameCheck)) .ToList(); // Configure assembly resolver for this assembly IgnoringExceptionsAssemblyResolver assemblyResolver = CreateAssemblyResolver(resolvedAllowedAssemblyReferences); AssemblyDefinitionCachedData assemblyDefinitionCachedData = GetAssemblyDefinitionCachedData(sourceInjecteeAssembly.AssemblyPath, assemblyResolver); Log.DebugFormat( "Calculating injectee methods in assembly '{0}'", assemblyDefinitionCachedData.AssemblyDefinition.MainModule.FullyQualifiedName); List <MethodDefinition> filteredInjecteeMethods = GetFilteredInjecteeMethods(assemblyDefinitionCachedData, ignoredMemberReferences); ResolvedInjecteeAssembly resolvedInjecteeAssembly = new ResolvedInjecteeAssembly( assemblyDefinitionCachedData.AssemblyDefinition, filteredInjecteeMethods, resolvedAllowedAssemblyReferences, assemblyResolver ); return(resolvedInjecteeAssembly); }