1

次のコードを使用して、ユーザー定義の場所にある厳密な名前のアセンブリを AppDomain に読み込もうとしています。

    AppDomainSetup ads1 = new AppDomainSetup();
    if (ads1.PrivateBinPath != null)
    {
        ads1.PrivateBinPath += ads1.PrivateBinPath.Length == 0 ? "" : Path.PathSeparator.ToString();
    }
    ads1.PrivateBinPath += @"c:\work\abc1";
    sandbox1 = AppDomain.CreateDomain("sandbox1", null, ads1);
    Object o1 = sandbox1.CreateInstanceFromAndUnwrap(@"abc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f10808f3df0adc34", "Abc.Def");

実行すると、次のエラーが表示されます。

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'file:///C:\Users\gel\Documents\Visual Studio 2012\Projects\ConsoleApplicat
ion1\ConsoleApplication1\bin\Debug\abc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f10808f3df0adc34' or one of its dependencies. The system cannot find the fil
e specified.
   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stack
Mark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& st
ackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& st
ackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boole
an forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
   at System.Reflection.Assembly.LoadFrom(String assemblyFile, Evidence securityEvidence)
   at System.Activator.CreateInstanceFromInternal(String assemblyFile, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, C
ultureInfo culture, Object[] activationAttributes, Evidence securityInfo)
   at System.AppDomain.CreateInstanceFrom(String assemblyFile, String typeName)
   at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName)
   at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName)
   at ConsoleApplication1.Program.Main(String[] args) in c:\Users\gel\Documents\Visual Studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\Program.cs:li
ne 69

AppDomain が PrivateBinPath をまったく見ていないかのようです。私は何をしていないのですか?エクスプローラー ウィンドウで再確認したところ、PrivateBinPath で指定した場所にアセンブリが表示されます。Assembly.LoadFile を実行して正しいパスを指定するだけで問題なく動作しますが、別の AppDomain にロードしようとする目的が無効になります。

4

2 に答える 2

2

私はあなたのコードを変更しました、そしてこれはちょうどうまくいきます。実行する必要のある変更を確認してください。

        AppDomainSetup ads1 = new AppDomainSetup();
        if (ads1.PrivateBinPath != null)
        {
            ads1.PrivateBinPath += ads1.PrivateBinPath.Length == 0 ? "" : Path.PathSeparator.ToString();
        }
        ads1.PrivateBinPath += @"D:\ConsoleApplication1\ClassLibrary1\bin\debug";
        AppDomain sandbox1 = AppDomain.CreateDomain("sandbox1", null, ads1);
        Object o1 = sandbox1.CreateInstanceFromAndUnwrap(@"ClassLibrary1.dll", "ClassLibrary1.Class1");
于 2012-11-24T08:37:54.637 に答える
1

そのアセンブリを新しいAppDomainではなく、現在のAppDomainにロードできないと思います(likleyが正常にロードした場所)。

「タイプを別のドメインにリークする」と呼ばれることもあり、作成されたオブジェクトを直接使用しようとすると発生します。これを回避するには、他のAppDomainでクラスを完全に作成し(つまり、作成を処理するカスタムコードを実行して)、両方のドメインで認識されているインターフェイス/クラスのみを公開する必要があります。詳細については、アンロード可能なプラグインを確認してください。

記事から採用されたコードの短い部分-他のAppDomainでRemoteLoaderクラスを作成しCreateInstanceFromAndUnwrap、そのオブジェクトを使用して新しいAppDomainで他のタイプをロード/管理します。

public class RemoteLoader : MarshalByRefObject
{ 
    public void Load(string assemblyName, string typeName)
    {
        object instance = Activator.CreateInstance(assemblyName, typeName);
        //Do something with instance, or return shared interface of it.
    }
}

補足:教育目的で行う場合を除き、MEFなどの既存のプラグインフレームワークの使用を検討してください。

于 2012-11-24T06:33:39.337 に答える