2010-03-23 24 views
3

我正在編寫一個程序,該程序將允許加載特定的託管.DLL文件並與之一起玩。由於我想卸載.DLL文件,我創建了兩個AppDomain - 一個用於應用程序本身,另一個用於當前加載的.DLL文件。由於加載的.DLL中的大多數對象都沒有很好的序列化,因此我創建了一個包裝類,它將對象本身保留在其自己的AppDomain中,並將一些反射函數公開給主應用程序AppDomain。.NET遠程處理異常:權限被拒絕:無法遠程調用非公共或靜態方法

然而,當我嘗試調用一個方法的遠程對象上我被卡住有例外:

權限被拒絕:無法遠程調用非公共或靜態方法。

這很奇怪,因爲我根本沒有使用任何非公共或靜態方法。從本質上說,我有什麼是:

class RemoteObjectWrapper: MarshalByRefObject 
{ 
    private Type SourceType; 
    private object Source; 

    public RemoteObjectWrapper(object source) 
    { 
     if (source == null) 
      throw new ArgumentNullException("source"); 
     this.Source = source; 
     this.SourceType = source.GetType(); 
    } 
    public T WrapValue<T>(object value) 
    { 
     if (value == null) 
      return default(T); 
     var TType = typeof(T); 
     if (TType == typeof(RemoteObjectWrapper)) 
      value = new RemoteObjectWrapper(value); 
     return (T)value; 
    } 
    public T InvokeMethod<T>(string methodName, params object[] args) 
    { 
     return WrapValue<T>(SourceType.InvokeMember(methodName, 
      System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.Instance | 
      System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public, null, this.Source, args)); 

    } 
} 

而我得到的異常,當我嘗試做:

var c = SomeInstanceOfRemoteObjectWrapper.InvokeMethod<RemoteObjectWrapper>("somePublicMethod", "some string parameter"); 

這是怎麼回事?據我所知,InvokeMethod方法甚至沒有執行,當我嘗試運行它時拋出異常。

補充:澄清 - SomeInstanceOfRemoteObjectWrapper在.DLL的AppDomain中構造,然後回到我的主要的AppDomain,該InvokeMethod<T>()從我的主要的AppDomain叫(我希望它在.DLL的AppDomain中執行)。

+1

看到堆棧跟蹤和調用代碼以及遠程對象代碼會很有用,但聽起來像somePublicMethod可能是靜態的。 – pdr 2010-03-23 04:28:33

+0

@pdr - 不,執行永遠不會傳入'InvokeMethod'。這個例外情況正好出現在上面的行,堆棧跟蹤也證明了這一點。我不會在這裏發佈它,因爲它不包含其他有用的信息,但引發異常的代碼行就是這一行,並且沒有內部異常或任何內容。 – 2010-03-23 11:44:37

回答

5

即使方法InvokeMethod<T>是公開的,它包含在內部類中。 C#中沒有修飾符使其成爲內部。因此,InvokeMethod<T>的有效可見性是內部的,您正在獲得例外。公開製作RemoteObjectWrapper應該解決這個問題。

+0

奇怪......這個作品...但爲什麼其他類似的類都不需要它?這是唯一需要它的遠程對象包裝類(我有幾個包裝特定對象的包裝類,這些不受影響) – 2010-03-23 11:41:52

2

我有完全相同的問題。如果你的對象,如:

class MyClass : MarshalByRefObject 
{ 
    public T Foo<T>() where T : MarshalByRefObject { 
    // stuff 
    } 
} 

調用與內部T型做工精細MyClass.Foo但只要只能作爲你的MyClass的對象並不遙遠。我想這是因爲你不一定假設你打電話的地方有任何訪問T.但是,當你無法使你使用公開的類型時非常尷尬。有時你能避開它通過包裝或更換美孚:

class MyClass : MarshalByRefObject 
{ 
    public object Foo(Type t) { 
    // stuff 
    } 
} 

這是不是類型安全可言,需要在主叫方一側的演員。我不知道是否有更好的解決方案,但是,如果你不能公開你的內部類型。

相關問題