C# 在运行时加载引用调用程序集的程序集

C# 在运行时加载引用调用程序集的程序集,c#,reference,assemblies,runtime,C#,Reference,Assemblies,Runtime,我的应用程序加载位于其执行路径中的所有库程序集,并对包含的类执行预先已知的方法 现在,我需要对引用我的应用程序集的程序集执行相同的操作。这可能吗?我是否应该意识到任何负面影响 总成: public abstract class TaskBase { public abstract void DoWork(); } LoadAssemblyFromFile("Assembly0001.dll"); Assembly0001.Task1.DoWork(); 子程序集:

我的应用程序加载位于其执行路径中的所有库程序集,并对包含的类执行预先已知的方法

现在,我需要对引用我的应用程序集的程序集执行相同的操作。这可能吗?我是否应该意识到任何负面影响

总成:

public abstract class TaskBase 
{ 
    public abstract void DoWork(); 
}  

LoadAssemblyFromFile("Assembly0001.dll");  
Assembly0001.Task1.DoWork();  
子程序集:

public sealed class Task1: MasterAssembly.TaskBase  
{ 
    public override void DoWork { /* whatever */ } 
}

根据我的经验,这没有什么错。实际上,以
AssemblyCatalog
(您的实现位于主程序集中)和
DirectoryCatalog
(接口的实现位于特定目录中的程序集中)的形式使用此技术


这两种方法都可以在一个
聚合目录中一起使用,没有问题。

是的,这是可能的。只要您的主程序集不引用子程序集,就可以了。否则,您将具有循环依赖关系

主程序集将只加载子程序集,而对它们一无所知,只知道它们实现了一个接口。这样,主程序集就不需要引用子程序集

据我所知,没有问题。我们成功地将此技术用于某些场景。

唯一的“问题”是您无法在主程序集中写入Assembly0001.Task1,但您可以在加载的程序集中找到正确的任务并调用该任务:

var asm = LoadAssemblyFromFile("Assembly0001.dll");
var taskType = asm.GetTypes().FirstOrDefault(t => typeof(TaskBase).IsAssignableFrom(t));
var task = (TaskBase)Activator.CreateInstance(taskType);
task.DoWork();

您仍然需要添加一些额外的安全检查:)

您没有发布LoadAssemblyFromFile(“…”)方法的代码,但如果它使用Assembly.LoadFrom()或Assembly.LoadFile()加载程序集,则可能会出现InvalidCastException、MissingMethodException或其他异常,尤其是当您的应用程序和加载的程序集都引用相同的其他程序集时。LoadFrom()和LoadFile()在应用程序所在的绑定上下文之外的绑定上下文中加载程序集。有关详细说明,请参阅。

我一直在这样做,没有任何问题。我遇到的唯一问题(实际上有几次)是主程序集的版本管理。如果您在不重新编译子对象的情况下对主对象进行更改,您可能会遇到一些奇怪的问题。@M.Babcock:谢谢。出于好奇,什么样的问题?我不会在重新编译时自动增加程序集版本。我认为这应该绕过你可能遇到的任何问题。您的想法?我遇到的最常见的问题是,方法定义的更改破坏了向后兼容性,但在其他情况下,我遇到了可怕的“类型在Master和Master中都定义”异常(从内存中定义,所以不是文本,但足够接近,您会识别它)。谢谢。在上下文之外,是否有一种方法可以在磁盘上不存在程序集文件的情况下从内存加载程序集?这些定期发布的程序集存在于一个中央数据库中,我更愿意让用户很难掌握它们。当然,我知道实现这一点没有简单的方法。是的,我们有这样的移动应用程序。程序集二进制文件存储在数据库中,以这种方式检索和加载。你也可以做同样的事情。找到它:Assembly.Load(byte[])。当然可以。按类型创建运行时实例是实现这一点的唯一方法。你会推荐什么样的安全检查?应用程序确实需要确保它正在执行我们自己的代码(可能通过单向散列)。还有什么呢?通常只是空检查,如果你真的想创建一个沙盒来运行你的任务,它可能会变得有点困难。