在新的appdomain中启动第三方DLL中存在的方法

时间:2013-02-22 10:32:42

标签: c#-4.0 appdomain

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DoCallBack
{
    class Program
    {
        static void Main(string[] args)
        {
            AppDomain newDomain = AppDomain.CreateDomain("New Domain");
            Console.WriteLine(newDomain.BaseDirectory);
            newDomain.DoCallBack(new CrossAppDomainDelegate(SayHello));
            AppDomain.Unload(newDomain);
        }
    }
}

我想在新的应用程序域中调用SayHello()方法。让我们假设,HelloMethod DLL是第三方,我没有代码。我只有装配。但我知道它有SayHello()方法。我该怎么办?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HelloMethod
{
    class Program
    {
        static void Main(string[] args)
        {
        }

        static void SayHello()
        {
            Console.WriteLine("Hi from " + AppDomain.CurrentDomain.FriendlyName);
        }
    }
}

在当前的代码中,它的给出错误“名称'SayHello'在当前上下文中不存在”

1 个答案:

答案 0 :(得分:2)

如果尚未加载程序集,则必须加载程序集。有两种方法可以做到:

  1. 从项目中引用程序集,然后执行:

    newDomain.DoCallBack(new CrossAppDomainDelegate(HelloMethod.Program.SayHello));
    

    如果您不介意在自己的项目中引用第三方程序集,这是可以的。这也意味着您在编译时知道要调用的程序集,类型和方法。

  2. 自己加载第三方程序集并执行特定方法:

    /// <summary>
    /// To be executed in the new AppDomain using the AppDomain.DoCallBack method.
    /// </summary>
    static void GenericCallBack()
    {                       
        //These can be loaded from somewhere else like a configuration file.
        var thirdPartyAssemblyFileName = "ThirdParty.dll";
        var targetTypeFullName = "HelloMethod.Program";
        var targetMethodName = "SayHello";
    
        try
        {
            var thirdPartyAssembly = Assembly.Load(AssemblyName.GetAssemblyName(thirdPartyAssemblyFileName));
    
            var targetType = thirdPartyAssembly.GetType(targetTypeFullName);
    
            var targetMethod = targetType.GetMethod(targetMethodName);
    
            //This will only work with a static method!           
            targetMethod.Invoke(null, null);             
        }
        catch (Exception e)
        {
            Console.WriteLine("Callback failed. Error info:");
            Console.WriteLine(e);
        }
    }
    

    如果您正在寻找一种更灵活的方法从第三方程序集调用公共静态方法,则可以使用此方法。请注意,几乎所有东西都在try-catch中,因为很多东西都可能出错。那是因为这些“反射”调用中的每一个都会抛出异常。最后注意,这种方法的工作原理是让第三方程序集及其所有依赖项位于应用程序的基目录或其中一个私有bin路径中。