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() メソッドがあることは知っています。私に何ができる?

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

この現在のコードでは、「The name 'SayHello' does not exist in the current context」というエラーが表示されます

4

1 に答える 1

2

アセンブリがまだロードされていない場合は、アセンブリをロードする必要があります。それを行うには 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);
        }
    }
    

    これは、サード パーティのアセンブリから public static メソッドを呼び出すためのより柔軟な方法を探している場合に使用できます。ここでは多くのことがうまくいかない可能性があるため、ほとんどすべてが try-catch 内にあることに注意してください。これは、これらの「リフレクション」呼び出しのそれぞれが例外をスローする可能性があるためです。最後に、このアプローチを機能させるには、サード パーティのアセンブリとそのすべての依存関係をアプリケーションのベース ディレクトリまたはプライベート ビン パスの 1 つに配置する必要があることに注意してください。

于 2013-02-22T19:07:52.447 に答える