2011-06-27 11 views
6

kilitlemek vermemek için bir test kütüphanesigölge kopyalama düzeneğini

public class Test 
{ 
    public int Add(int val1, int val2) 
    { 
     return val1 + val2; 
    } 
} 

Ve onu aramak için bir proje oluşturduk? Derlemem neden kilitli?

DÜZENLEME: kodlanmış montaj adıyla:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Reflection; 
using System.IO; 

namespace Loader 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      AppDomainSetup ads = new AppDomainSetup(); 

      String fullPath = @"c:\users\myuser\documents\visual studio 2010\Projects\ShadowCopy\Loader\bin\Debug\Lib.dll"; 

      ads.ShadowCopyFiles = "true"; 
      ads.ApplicationName = "AppName"; 
      ads.ShadowCopyDirectories = Path.GetDirectoryName(fullPath); 
      //ads.ApplicationBase = Path.GetDirectoryName(fullPath); 
      //ads.PrivateBinPath = Path.GetDirectoryName(fullPath); 
      ads.CachePath = @"c:\users\myuser\documents\visual studio 2010\Projects\ShadowCopy\Loader\bin\Debug\Cache\"; 

      AppDomain ad = AppDomain.CreateDomain("myName" + ads.ApplicationName, null, ads); 

      ad.AssemblyResolve += new ResolveEventHandler(ad_AssemblyResolve); 

      Console.WriteLine(ad.ShadowCopyFiles); 
      Console.WriteLine(ad.SetupInformation.ShadowCopyDirectories); 

      try 
      { 
       //Assembly assembly = ad.Load(AssemblyName.GetAssemblyName(fullPath)); 
       //dynamic obj = ad.CreateInstanceAndUnwrap(assembly.GetName().Name, "Lib.Test"); 

       dynamic obj = ad.CreateInstanceAndUnwrap("Lib", "Lib.Test"); 

       Console.WriteLine(obj.Add(1, 7)); 

       Console.ReadKey(); 

       Console.WriteLine(obj.Add(1, 90)); 
      } 
      catch(Exception e) 
      { 
       Console.WriteLine(e.Message); 
      } 
     } 

     static Assembly ad_AssemblyResolve(object sender, ResolveEventArgs args) 
     { 
      return Assembly.LoadFile(@"c:\users\myuser\documents\visual studio 2010\Projects\ShadowCopy\Loader\bin\Debug\Lib.dll"); 
     } 
    } 
} 

O assebly önbelleğe da kilitli olduğunu ilginçtir.

DÜZENLEME 2: Burada

Lib.Test bir yöntem engellenir assenbly erişilen Bir kez aksamı

Console.WriteLine(obj.Add(1, 7)); 

engellemek için kod hattıdır.

Çözüm ne olabilir? İki seçeneğiniz vardır

+0

Lütfen tam olarak aldığınız hatayı gönderin. –

+0

Söylediğim kesin problem şu ki Lib.dll grubu kilitlendi. Örneğin, uygulama çalışırken onu yeniden gönderemiyorum. – NDeveloper

+0

Kodunuzun yapı tipini birincil uygulama alanına yüklemesini önlemek için 3. montajda bir arabirim kullanmanız gerekir. LoadFile kullanmayın. –

cevap

0

, çalışma zamanında montaj öncesi adı bulmak gerekir ve kodlanmış varsa veya daha önce çalışma zamanına bilmiyorsanız size FullName biliyor musunuz ikinci kütüphaneyi yazmaya gerek ve bunu AppDomain'de yükleyin. İkinci kütüphane Bu gölge kopyası ile açmak gerektiği gibi kilitlemeden yeni AppDomain içinde hedef yükleyeceğini

public Assembly GetAssemblyForOtherAppDomain(string path) 
{ 
    return Assembly.LoadFile(path) 
} 

bir işlevi vardır bir sınıf olacak.

DÜZENLEME: En yöntem işe yaramadı neden olarak, bu yük onu kilitleme hakkı konusunda nerede ve dosyayı kilitler Assembly.LoadFile(), çalıştırdığınızda once a assembly is loaded in to a AppDomain it can not be unloaded.

+0

Elbette derleme ismini biliyorum ... ama olmayacak yardım et. Aynı problemi denedim. – NDeveloper

+0

Lütfen yeni kodla güncellenmiş soruları kontrol edin. – NDeveloper

1

sadece ana AppDomain takımını yüklüyoruz. Doğrudan AppDomain'inize yüklemek istiyorsanız, doğrudan AppDomain'in belirttiğiniz parametrelere göre çözmesine izin vererek, AppDomain.Load() doğrudan kullanmanız gerekir. Montaj, ana Uygulama Alanınızda yüklenmediğinden, bu yöntemin Ana yönteminizden erişilemeyeceğini unutmayın. (Dinamik atamak zaman daha da dinamik bir vekil içine sarılmış olur.) Kişisel Lib.Test manevra sisteminiz proxy oluşturabilmeleri MarshalByRefObject türetmek gerekir


DÜZENLEME: Upon

daha fazla düşündüm ki, buradaki problemin, dinamik proxy üzerindeki yöntemi çağırmak için, nesnenin üzerine yansıtması gerektiğidir (bu, diğer AppDomain'inizdeki örnek için şeffaf bir proxy'dir). Özgün sınıf türü ('gizli' şeffaf proxy türü değil) üzerinde, bu, uygulamanın yerel AppDomain'de bir kopyasını yüklemesine neden olur (böylece kilitler.) Bu, AppDomain isolat kullanıldığında bir nedenidir. İyon, genellikle nesneyi, hem 'ana' uygulama hem de barındırılan AppDomain'in referans gösterebileceği ayrı bir derlemede tanımlanmış bir arabirime atarsınız. Her biri, yüklenen arayüz düzeneğinin kendi kopyasını alacak, ancak şimdi 'uygulama' topluluğu izole edildi.

+0

Lütfen düzenlenmiş koda bakınız ... Assembly.LoadFile yok. Ayrıca MarshalByRefObject'ten Lib.Test türetilmiş ve [Seri hale getirilebilir] ayarlanmış, ancak yine de aynı .... Başka ne yapmam gerektiğini hayal edemiyorum. – NDeveloper

+0

@NDeveloper, bu yeni durumda, gölge kopyalamayı atlayan ve dosyayı doğrudan yükleyen LoadFile'ı arayarak, AppDomain'i Mecliste çözümlemek için zorluyorsunuz. Dosyayı gölge kopyalama mekanizmasını kullanarak yüklemek isterseniz, derlemenin Tam Adı'nı CreateInstanceAndUnwrap'e geçirmeniz ve AppDomain'in kendi dosya çözünürlüğünü yapmasına izin vermeniz gerekir. –

+0

Ancak ad_AssemblyResolve hiçbir zaman çağrılmadı, bu nedenle anlattığınız her şey. – NDeveloper