有没有办法强制所有引用的程序集加载到应用程序域?

我的项目是这样设置的:

  • 项目“定义”
  • 项目实施”
  • “消费者”项目

项目“消费者”引用“定义”和“实施”,但不会在“实施”中静态引用任何types。

当应用程序启动时,Project“Consumer”在“Definition”中调用静态方法,需要在“Implementation”中findtypes,

有没有办法强迫任何引用的程序集加载到应用程序域而不知道path或名称,最好是不必使用一个完整的IOC框架?

这似乎是诀窍:

var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList(); var loadedPaths = loadedAssemblies.Select(a => a.Location).ToArray(); var referencedPaths = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll"); var toLoad = referencedPaths.Where(r => !loadedPaths.Contains(r, StringComparer.InvariantCultureIgnoreCase)).ToList(); toLoad.ForEach(path => loadedAssemblies.Add(AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(path)))); 

正如Jon所说,理想的解决scheme需要recursion到每个加载程序集的依赖关系中,但是在我的具体情况中,我不必担心它。


更新:包含在.NET 4中的托pipe扩展性框架(System.ComponentModel)有更好的设施来完成这样的事情。

您可以使用Assembly.GetReferencedAssemblies获取一个AssemblyName[] ,然后调用Assembly.Load(AssemblyName)每个上。 当然你需要recursion – 但是最好跟踪你已经加载的程序集:)

只是想分享一个recursion的例子。 我在我的启动例程中调用LoadReferencedAssembly方法,如下所示:

 foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { this.LoadReferencedAssembly(assembly); } 

这是recursion方法:

 private void LoadReferencedAssembly(Assembly assembly) { foreach (AssemblyName name in assembly.GetReferencedAssemblies()) { if (!AppDomain.CurrentDomain.GetAssemblies().Any(a => a.FullName == name.FullName)) { this.LoadReferencedAssembly(Assembly.Load(name)); } } } 

如果您使用Fody.Costura或任何其他汇编合并解决scheme,则接受的答案将不起作用。

以下加载任何当前加载的程序集的引用程序集。 recursion是给你的。

 var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList(); loadedAssemblies .SelectMany(x => x.GetReferencedAssemblies()) .Distinct() .Where(y => loadedAssemblies.Any((a) => a.FullName == y.FullName) == false) .ToList() .ForEach(x => loadedAssemblies.Add(AppDomain.CurrentDomain.Load(x))); 

因为今天我必须从一个特定的path加载一个程序集+依赖关系,所以我写了这个类来完成它。

 public static class AssemblyLoader { private static readonly ConcurrentDictionary<string, bool> AssemblyDirectories = new ConcurrentDictionary<string, bool>(); static AssemblyLoader() { AssemblyDirectories[GetExecutingAssemblyDirectory()] = true; AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; } public static Assembly LoadWithDependencies(string assemblyPath) { AssemblyDirectories[Path.GetDirectoryName(assemblyPath)] = true; return Assembly.LoadFile(assemblyPath); } private static Assembly ResolveAssembly(object sender, ResolveEventArgs args) { string dependentAssemblyName = args.Name.Split(’,’)[0] + ".dll"; List<string> directoriesToScan = AssemblyDirectories.Keys.ToList(); foreach (string directoryToScan in directoriesToScan) { string dependentAssemblyPath = Path.Combine(directoryToScan, dependentAssemblyName); if (File.Exists(dependentAssemblyPath)) return LoadWithDependencies(dependentAssemblyPath); } return null; } private static string GetExecutingAssemblyDirectory() { string codeBase = Assembly.GetExecutingAssembly().CodeBase; var uri = new UriBuilder(codeBase); string path = Uri.UnescapeDataString(uri.Path); return Path.GetDirectoryName(path); } }