2013-02-22 67 views
0
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()方法。我能做什么?在新的应用程序域中启动第三方DLL中的方法

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); 
     } 
    } 
} 

在当前的代码,它给错误

回答

2

你将不得不如果尚未加载它加载程序集“名‘的SayHello’并不在当前的背景下存在”。两种方法做到这一点:从项目

  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路径中。

+0

感谢分配,**新的CrossAppDomainDelegate **是必要的吗?为什么我们可以没有这个运行? – SHRI 2013-02-25 10:30:23

+0

@SHRI有必要!编译器为您声明的每个委托类型生成代码。 CrossAppDomainDelegate可能让编译器知道委托应该从MarshalByRefObject派生,以允许跨AppDomain通信。这是我的猜测。重要的是你需要使用CrossAppDomainDelegate。 – 2013-02-25 13:00:58

相关问题