2
using System;
using System.IO;
using System.Reflection;
using System.Text;
using MyApp.Logging;

namespace MyApp.SmsService.Common
{
    public class MyAppAppDomain:MarshalByRefObject
    {
        private readonly AppDomainSetup domaininfo;
        private readonly AppDomain appDomain;
        public static string libDllPath;

        public MyAppAppDomain(string appDomainName) //Constructor
        {
            //Setup the App Domain Parameters
            domaininfo = new AppDomainSetup();
            domaininfo.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
            domaininfo.DisallowBindingRedirects = false;
            domaininfo.DisallowCodeDownload = true;
            domaininfo.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

            // Create the application domain.
            appDomain = AppDomain.CreateDomain(appDomainName, null, domaininfo);

            //Set the dll path using Static class ref.

            //Dependency resolution handler
            appDomain.AssemblyResolve += LoadFromLibFolder; /*Exception*/
        }

        private static Assembly LoadFromLibFolder(object sender, ResolveEventArgs args)
        {

            if (libDllPath != null)
            {
                string assemblyPath = Path.Combine(libDllPath, new AssemblyName(args.Name).Name + ".dll");

                if (File.Exists(assemblyPath) == false)
                {
                    return null;
                }
                Assembly assembly = Assembly.LoadFrom(assemblyPath);
                //Assembly dependancy resolved.

                return assembly;
            }

            return null;
        }

        public Object getNewInstanceOf(string fullyQualifiedTypeName)
        {
            return appDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, fullyQualifiedTypeName);
        }

        public Type getTypeOf(string fullyQualifiedTypeName)
        {
            return getNewInstanceOf(fullyQualifiedTypeName).GetType();
        }

        public void unloadDomain()
        {
            AppDomain.Unload(appDomain);
        }
    }
}

上記のクラスは、アプリケーション ドメインをセットアップおよび破棄するために作成するラッパーです。ただし、私の Web サービスでは、MyAppAppDomain のオブジェクトをインスタンス化するたびに FileNotFoundException [dll xyz.dll の読み込みに失敗しました] が発生します。

以下は例です:

MyAppAppDomain.libDllPath = appDllLibPath; //Some directory other than bin.
pluginDomain = new MyAppAppDomain("SmsServicePlugins"); //Throws FileNotFoundException.

デバッグすると、例外の原因となった行は、上記で / exception / としてマークされた行で、MyAppAppDomain のコンストラクター内にあることがわかります。

何がうまくいかないのですか?

編集:

他の記事を読んでいて、ドメイン間でオブジェクトを表示できないことを読みました。これは、オブジェクトを両方のドメインでシリアル化でき (MarshalByRefObject を使用)、プロキシ経由でアクセスできる場合にのみ発生します。

誰かが上記のコードの問題を指摘できれば、非常に役立ちます。その間、私はマーシャリングとプロキシについてもっと学ぼうとしています。

4

1 に答える 1

0

最初の問題は、アプリ ドメイン ラッパー内ですべてを実行しようとしていることです。これは、実際には 2 つの異なるコンポーネントです。必要な最初のコンポーネントは、から継承するMarshalByRefObject(または としてマークされたSerializable) 新しいアプリ ドメイン内に作成するオブジェクトです。もう 1 つは現在の内部AppDomainに存在し、新しい を作成するために使用されますAppDomain

私の言いたいことを理解するには、msdn のを見てください。

ただし、エラーはおそらく、DLL へのパスが間違っている可能性が高いです。どの行が例外をスローしているかを示す完全なスタック トレースを表示できますか?

于 2012-06-14T13:42:49.463 に答える