加载程序集、查找类和调用 Run() 方法的正确方法

问题描述:

示例控制台程序.

class Program
{
    static void Main(string[] args)
    {
        // ... code to build dll ... not written yet ...
        Assembly assembly = Assembly.LoadFile(@"C:dyn.dll");
        // don't know what or how to cast here
        // looking for a better way to do next 3 lines
        IRunnable r = assembly.CreateInstance("TestRunner");
        if (r == null) throw new Exception("broke");
        r.Run();

    }
}

我想动态构建一个程序集(.dll),然后加载该程序集,实例化一个类,并调用该类的 Run() 方法.我应该尝试将 TestRunner 类转换为某些东西吗?不确定一个程序集中的类型(动态代码)如何知道我的(静态程序集/外壳应用程序)中的类型.仅使用几行反射代码在对象上调用 Run() 是否更好?这段代码应该是什么样的?

I want to dynamically build an assembly (.dll), and then load the assembly, instantiate a class, and call the Run() method of that class. Should I try casting the TestRunner class to something? Not sure how the types in one assembly (dynamic code) would know about my types in my (static assembly / shell app). Is it better to just use a few lines of reflection code to call Run() on just an object? What should that code look like?

更新:威廉埃德蒙森 - 见评论

UPDATE: William Edmondson - see comment

使用 AppDomain

将程序集加载到自己的更安全、更灵活AppDomain 首先.

而不是之前给出的答案:

var asm = Assembly.LoadFile(@"C:myDll.dll");
var type = asm.GetType("TestRunner");
var runnable = Activator.CreateInstance(type) as IRunnable;
if (runnable == null) throw new Exception("broke");
runnable.Run();

我建议如下(改编自 这个对相关问题的回答):

I would suggest the following (adapted from this answer to a related question):

var domain = AppDomain.CreateDomain("NewDomainName");
var t = typeof(TypeIWantToLoad);
var runnable = domain.CreateInstanceFromAndUnwrap(@"C:myDll.dll", t.Name) as IRunnable;
if (runnable == null) throw new Exception("broke");
runnable.Run();

现在您可以卸载程序集并拥有不同的安全设置.

Now you can unload the assembly and have different security settings.

如果您想为程序集的动态加载和卸载提供更大的灵活性和功能,您应该查看托管加载项框架(即 System.AddIn 命名空间).有关详细信息,请参阅有关 MSDN 上的加载项和可扩展性的文章>.

If you want even more flexibility and power for dynamic loading and unloading of assemblies, you should look at the Managed Add-ins Framework (i.e. the System.AddIn namespace). For more information, see this article on Add-ins and Extensibility on MSDN.