2013-02-22 68 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

相關問題