1

リフレクションを使用して AppDomain でコードを実行しようとしています。これが私のコードです:

AppDomain appDomain = GetSomehowAppDomain(); 
string typeAssembly = GetTypeAssembly();
string typeName = GetTypeName();
object targetObject = appDomain.CreateInstanceAndUnwrap(typeAssembly, typeName);
MethodInfo methodInfo = targetObject.GetType().GetMethod(methodName);
object result = methodInfo.Invoke(targetObject, methodParams);

このコードが Web サイトで実行されている場合、すべて問題ありません。しかし、上記のコードを呼び出そうとする WCF サービスを呼び出すコンソール アプリケーションからこれを実行しているときはmethodInfo、最後の行nullに到達しています。NullReferenceException

ちなみにtargetObjectSystem.Runtime.Remoting.Proxies.__TransparentProxy型であり、GoF パターンでプロキシする場合は、プロキシの元のソースである型のメンバーにアクセスできることを意味します。しかし、型targetObjectのメンバーはありませんtypeName

を使用targetObject.GetType().GetMethods()して、7つの方法があることがわかりました。

  1. GetLifetimeService
  2. InitializeLifetimeService
  3. CreateObjRef
  4. ToString
  5. 等しい
  6. GetHashCode
  7. GetType

targetObjectタイプのプロキシであると予想されますWorkflowManager

public class WorkflowsManager : MarshalByRefObject, ISerializable, IDisposable, IWorkflowManager

4

1 に答える 1

1

Panos Rontogiannisのコメントのおかげで、コンソール アプリケーションではなく、WCF コードで実際にアセンブリをロードするという質問からの指示が欠けていることに気付きました。

GAC からの実際のアセンブリ バージョンが、WCF コードで使用する予定のものであることを確認してください。

あなたのシナリオに似たソリューションを更新しました。

//After building the library, add it to the GAC using "gacutil -i MyLibrary.dll"
using System;
using System.Runtime.Serialization;

namespace MyLibrary
{
    [Serializable]
    public class MyClass : MarshalByRefObject
    {
        public string Work(string name)
        {
            return String.Format("{0} cleans the dishes", name);
        }
    }
}

Web アプリケーションのサービス クラス定義:

using System;
using System.Reflection;
using System.ServiceModel;

namespace WebApplication1
{
    [ServiceContract]
    public class MyService : IMyService
    {
        [OperationContract]
        public string DoWork(string name)
        {
            string methodName = "Work";
            object[] methodParams = new object[] { "Alex" };
            AppDomain appDomain = AppDomain.CreateDomain("");
            appDomain.Load("MyLibrary, Version=1.0.0.3, Culture=neutral, PublicKeyToken=0a6d06b33e075e91");
            string typeAssembly = "MyLibrary, Version=1.0.0.3, Culture=neutral, PublicKeyToken=0a6d06b33e075e91";
            string typeName = "MyLibrary.MyClass";
            object targetObject = appDomain.CreateInstanceAndUnwrap(typeAssembly, typeName);
            MethodInfo methodInfo = targetObject.GetType().GetMethod(methodName);
            string result = methodInfo.Invoke(targetObject, methodParams).ToString();
            return result;
        }
    }
}

WCF サービスを呼び出すコンソール アプリケーション:

using System;
using WebApplication1;

namespace ConsoleApplication12
{
    class Program
    {
        static void Main(string[] args)
        {
            WebApplication1.MyService myService = new MyService();
            Console.WriteLine(myService.DoWork("Alex"));
        }
    }
}
于 2012-12-18T22:08:38.547 に答える