Removes build manager type finder and friends

This commit is contained in:
Shannon
2020-03-11 12:43:46 +11:00
parent 8cb39ba583
commit 5ee2286436
8 changed files with 44 additions and 244 deletions

View File

@@ -1,102 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security;
using Umbraco.Core.Exceptions;
namespace Umbraco.Core.Composing
{
/// <summary>
/// lazily load a reference to all local assemblies and gac assemblies
/// </summary>
/// <remarks>
/// This is a modified version of: http://www.dominicpettifer.co.uk/Blog/44/how-to-get-a-reference-to-all-assemblies-in-the--bin-folder
///
/// We do this because we cannot use AppDomain.Current.GetAssemblies() as this will return only assemblies that have been
/// loaded in the CLR, not all assemblies.
/// See these threads:
/// http://issues.umbraco.org/issue/U5-198
/// http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app
/// http://stackoverflow.com/questions/2477787/difference-between-appdomain-getassemblies-and-buildmanager-getreferencedassembl
/// </remarks>
public class BruteForceAssemblyProvider : IAssemblyProvider
{
public BruteForceAssemblyProvider()
{
_allAssemblies = new Lazy<HashSet<Assembly>>(() =>
{
HashSet<Assembly> assemblies = null;
try
{
//NOTE: we cannot use AppDomain.CurrentDomain.GetAssemblies() because this only returns assemblies that have
// already been loaded in to the app domain, instead we will look directly into the bin folder and load each one.
var binFolder = GetRootDirectorySafe();
var binAssemblyFiles = Directory.GetFiles(binFolder, "*.dll", SearchOption.TopDirectoryOnly).ToList();
assemblies = new HashSet<Assembly>();
foreach (var a in binAssemblyFiles)
{
try
{
var assName = AssemblyName.GetAssemblyName(a);
var ass = Assembly.Load(assName);
assemblies.Add(ass);
}
catch (Exception e)
{
if (e is SecurityException || e is BadImageFormatException)
{
//swallow these exceptions
}
else
{
throw;
}
}
}
//Since we are only loading in the /bin assemblies above, we will also load in anything that's already loaded (which will include gac items)
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
{
assemblies.Add(a);
}
}
catch (InvalidOperationException e)
{
if (e.InnerException is SecurityException == false)
throw;
}
return assemblies;
});
}
private readonly Lazy<HashSet<Assembly>> _allAssemblies;
private string _rootDir = string.Empty;
public IEnumerable<Assembly> Assemblies => _allAssemblies.Value;
// FIXME - this is only an interim change, once the IIOHelper stuff is merged we should use IIOHelper here
private string GetRootDirectorySafe()
{
if (string.IsNullOrEmpty(_rootDir) == false)
{
return _rootDir;
}
var codeBase = Assembly.GetExecutingAssembly().CodeBase;
var uri = new Uri(codeBase);
var path = uri.LocalPath;
var baseDirectory = Path.GetDirectoryName(path);
if (string.IsNullOrEmpty(baseDirectory))
throw new PanicException("No root directory could be resolved.");
_rootDir = baseDirectory.Contains("bin")
? baseDirectory.Substring(0, baseDirectory.LastIndexOf("bin", StringComparison.OrdinalIgnoreCase) - 1)
: baseDirectory;
return _rootDir;
}
}
}

View File

@@ -10,6 +10,7 @@ using Umbraco.Core.Logging;
namespace Umbraco.Core.Composing
{
/// <inheritdoc cref="ITypeFinder"/>
public class TypeFinder : ITypeFinder
{
@@ -212,6 +213,11 @@ namespace Umbraco.Core.Composing
/// <returns></returns>
public virtual Type GetTypeByName(string name)
{
//NOTE: This will not find types in dynamic assemblies unless those assemblies are already loaded
//into the appdomain.
// This is exactly what the BuildManager does, if the type is an assembly qualified type
// name it will find it.
if (TypeNameContainsAssembly(name))

View File

@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
namespace Umbraco.Core.Composing
{
/// <summary>
/// TypeFinder config via appSettings
/// </summary>
internal class TypeFinderConfig : ITypeFinderConfig
{
private readonly ITypeFinderSettings _settings;
private IEnumerable<string> _assembliesAcceptingLoadExceptions;
public TypeFinderConfig(ITypeFinderSettings settings)
{
_settings = settings;
}
public IEnumerable<string> AssembliesAcceptingLoadExceptions
{
get
{
if (_assembliesAcceptingLoadExceptions != null)
return _assembliesAcceptingLoadExceptions;
var s = _settings.AssembliesAcceptingLoadExceptions;
return _assembliesAcceptingLoadExceptions = string.IsNullOrWhiteSpace(s)
? Array.Empty<string>()
: s.Split(',').Select(x => x.Trim()).ToArray();
}
}
}
}

View File

@@ -370,6 +370,8 @@ namespace Umbraco.Core.Runtime
/// </summary>
/// <returns></returns>
protected virtual ITypeFinder GetTypeFinder()
// TODO: Currently we are not passing in any TypeFinderConfig (with ITypeFinderSettings) which we should do, however
// this is not critical right now and would require loading in some config before boot time so just leaving this as-is for now.
=> new TypeFinder(Logger, new DefaultUmbracoAssemblyProvider(Assembly.GetEntryAssembly()));

View File

@@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security;
using System.Web.Compilation;
using Umbraco.Core.Composing;
using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Umbraco.Web.Composing
{
/// <summary>
/// Uses the BuildManager to provide a list of assemblies to scan
/// </summary>
internal class BuildManagerAssemblyProvider : BruteForceAssemblyProvider, IAssemblyProvider
{
private readonly Lazy<HashSet<Assembly>> _allAssemblies;
public BuildManagerAssemblyProvider(IIOHelper ioHelper,
IHostingEnvironment hostingEnvironment,
ILogger logger)
{
_allAssemblies = new Lazy<HashSet<Assembly>>(() =>
{
var isHosted = hostingEnvironment.IsHosted;
try
{
if (isHosted)
{
var assemblies = new HashSet<Assembly>(BuildManager.GetReferencedAssemblies().Cast<Assembly>());
//here we are trying to get the App_Code assembly
var fileExtensions = new[] { ".cs", ".vb" }; //only vb and cs files are supported
var appCodeFolder = new DirectoryInfo(ioHelper.MapPath(ioHelper.ResolveUrl("~/App_code")));
//check if the folder exists and if there are any files in it with the supported file extensions
if (appCodeFolder.Exists && fileExtensions.Any(x => appCodeFolder.GetFiles("*" + x).Any()))
{
try
{
var appCodeAssembly = Assembly.Load("App_Code");
if (assemblies.Contains(appCodeAssembly) == false) // BuildManager will find App_Code already
assemblies.Add(appCodeAssembly);
}
catch (FileNotFoundException ex)
{
//this will occur if it cannot load the assembly
logger.Error(typeof(TypeFinder), ex, "Could not load assembly App_Code");
}
}
return assemblies;
}
}
catch (InvalidOperationException e)
{
if (e.InnerException is SecurityException == false)
throw;
}
// Not hosted, just use the default implementation
return new HashSet<Assembly>(base.Assemblies);
});
}
IEnumerable<Assembly> IAssemblyProvider.Assemblies => _allAssemblies.Value;
}
}

View File

@@ -1,66 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Compilation;
using Umbraco.Core.Configuration;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Logging;
namespace Umbraco.Web.Composing
{
/// <summary>
/// An implementation of TypeFinder that uses the BuildManager to resolve references for aspnet framework hosted websites
/// </summary>
/// <remarks>
/// This finder will also try to resolve dynamic assemblies created from App_Code
/// </remarks>
internal class BuildManagerTypeFinder : TypeFinder, ITypeFinder
{
public BuildManagerTypeFinder(
ILogger logger,
IAssemblyProvider assemblyProvider,
ITypeFinderConfig typeFinderConfig = null) : base(logger, assemblyProvider, typeFinderConfig)
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
}
/// <summary>
/// Explicitly implement and return result from BuildManager
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
Type ITypeFinder.GetTypeByName (string name) => BuildManager.GetType(name, false);
/// <summary>
/// TypeFinder config via appSettings
/// </summary>
internal class TypeFinderConfig : ITypeFinderConfig
{
private readonly ITypeFinderSettings _settings;
private IEnumerable<string> _assembliesAcceptingLoadExceptions;
public TypeFinderConfig(ITypeFinderSettings settings)
{
_settings = settings;
}
public IEnumerable<string> AssembliesAcceptingLoadExceptions
{
get
{
if (_assembliesAcceptingLoadExceptions != null)
return _assembliesAcceptingLoadExceptions;
var s = _settings.AssembliesAcceptingLoadExceptions;
return _assembliesAcceptingLoadExceptions = string.IsNullOrWhiteSpace(s)
? Array.Empty<string>()
: s.Split(',').Select(x => x.Trim()).ToArray();
}
}
}
}
}

View File

@@ -21,8 +21,6 @@ namespace Umbraco.Web.Runtime
/// <remarks>On top of CoreRuntime, handles all of the web-related runtime aspects of Umbraco.</remarks>
public class WebRuntime : CoreRuntime
{
private BuildManagerTypeFinder _typeFinder;
/// <summary>
/// Initializes a new instance of the <see cref="WebRuntime"/> class.
/// </summary>
@@ -92,8 +90,6 @@ namespace Umbraco.Web.Runtime
#region Getters
//protected override ITypeFinder GetTypeFinder() => _typeFinder ?? (_typeFinder = new BuildManagerTypeFinder(IOHelper, HostingEnvironment, Logger, new BuildManagerTypeFinder.TypeFinderConfig(new TypeFinderSettings())));
protected override AppCaches GetAppCaches() => new AppCaches(
// we need to have the dep clone runtime cache provider to ensure
// all entities are cached properly (cloned in and cloned out)

View File

@@ -143,8 +143,6 @@
<Compile Include="Compose\AuditEventsComposer.cs" />
<Compile Include="Compose\BackOfficeUserAuditEventsComponent.cs" />
<Compile Include="Compose\BackOfficeUserAuditEventsComposer.cs" />
<Compile Include="Composing\BuildManagerAssemblyProvider.cs" />
<Compile Include="Composing\BuildManagerTypeFinder.cs" />
<Compile Include="Composing\CompositionExtensions\Installer.cs" />
<Compile Include="Composing\LightInject\LightInjectContainer.cs" />
<Compile Include="Editors\BackOfficePreviewModel.cs" />