public static IEnumerable <ExtensionReference> GenerateExtensionReferences(string fileName, ConsoleLogger logger) { BaseAssemblyResolver resolver = new DefaultAssemblyResolver(); resolver.AddSearchDirectory(Path.GetDirectoryName(fileName)); ReaderParameters readerParams = new ReaderParameters { AssemblyResolver = resolver }; AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(fileName, readerParams); var startupAttributes = assembly.Modules.SelectMany(p => p.GetCustomAttributes()) .Where(a => IsWebJobsStartupAttributeType(a.AttributeType, logger)); List <ExtensionReference> extensionReferences = new List <ExtensionReference>(); foreach (var attribute in startupAttributes) { var typeProperty = attribute.ConstructorArguments.ElementAtOrDefault(0); var nameProperty = attribute.ConstructorArguments.ElementAtOrDefault(1); TypeDefinition typeDef = (TypeDefinition)typeProperty.Value; string assemblyQualifiedName = Assembly.CreateQualifiedName(typeDef.Module.Assembly.FullName, GetReflectionFullName(typeDef)); string name; // Because we're now using static analysis we can't rely on the constructor running so have to get the name ourselves. if (string.Equals(attribute.AttributeType.FullName, FunctionsStartupAttributeType, StringComparison.OrdinalIgnoreCase)) { // FunctionsStartup always uses the type name as the name. name = typeDef.Name; } else { // WebJobsStartup does some trimming. name = GetName((string)nameProperty.Value, typeDef); } var extensionReference = new ExtensionReference { Name = name, TypeName = assemblyQualifiedName }; extensionReferences.Add(extensionReference); } return(extensionReferences); }
public static bool IsWebJobsStartupAttributeType(TypeReference attributeType, ConsoleLogger logger) { TypeReference currentAttributeType = attributeType; while (currentAttributeType != null) { if (string.Equals(currentAttributeType.FullName, WebJobsStartupAttributeType, StringComparison.OrdinalIgnoreCase)) { return(true); } try { currentAttributeType = currentAttributeType.Resolve()?.BaseType; } catch (FileNotFoundException ex) { // Don't log this as an error. This will almost always happen due to some publishing artifacts (i.e. Razor) existing // in the functions bin folder without all of their dependencies present. These will almost never have Functions extensions, // so we don't want to write out errors every time there is a build. This message can be seen with detailed logging enabled. string attributeTypeName = GetReflectionFullName(attributeType); string fileName = Path.GetFileName(attributeType.Module.FileName); logger.LogMessage($"Could not determine whether the attribute type '{attributeTypeName}' used in the assembly '{fileName}' derives from '{WebJobsStartupAttributeType}' because the assembly defining its base type could not be found. Exception message: {ex.Message}"); return(false); } } return(false); }
public IndentDisposable(ConsoleLogger logger) { _logger = logger; _logger.PushIndent(); }