Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
.NET, derleme yükleme üzerinde daha fazla denetim gerektiren uygulamalar için AppDomain.AssemblyResolve olayını sağlar. Uygulamanız bu olayı işleyerek normal yoklama yollarının dışından bir derlemeyi yük bağlamı içine yükleyebilir, yüklenecek birkaç derleme sürümünü seçebilir, dinamik bir derleme yayınlayabilir ve döndürebilir vb. Bu konu, olayla başa çıkma konusunda AssemblyResolve rehberlik sağlar.
Uyarı
Yalnızca yansıma bağlamında derleme yüklerini çözümlemek için, olay olarak bunun yerine AppDomain.ReflectionOnlyAssemblyResolve kullanın.
AssemblyResolve olayı nasıl çalışır?
AssemblyResolve olayı için bir işleyici kaydettiğinizde, çalışma zamanı ada göre bir derlemeye bağlanamadığında bu işleyici çağrılır. Örneğin, kullanıcı kodundan aşağıdaki yöntemleri çağırmak AssemblyResolve olayın tetik edilmesine neden olabilir:
İlk bağımsız değişkeni yüklenecek derlemenin görünen adını temsil eden bir dize olan AppDomain.Load yöntem aşırı yüklemesi veya Assembly.Load yöntem aşırı yüklemesi (yani Assembly.FullName özelliği tarafından döndürülen dize).
Öncelikli bağımsız değişkeni yüklenecek derlemeyi tanımlayan bir nesne olan AppDomain.Load yöntem aşırı yüklemesi veya Assembly.Load yöntem aşırı yüklemesi.
Bir Assembly.LoadWithPartialName yöntem aşırı yüklemesi.
Başka bir uygulama etki alanında bir nesne örneği oluşturan AppDomain.CreateInstance veya AppDomain.CreateInstanceAndUnwrap yöntemi aşırı yüklemesi.
Olay işleyicisi ne yapar?
Olay işleyicisi AssemblyResolve , özelliğinde ResolveEventArgs.Name yüklenecek derlemenin görünen adını alır. İşleyici derleme adını tanımıyorsa, null (C#), Nothing (Visual Basic) veya nullptr (Visual C++) döndürür.
İşleyici derleme adını tanırsa, isteği karşılayan bir derlemeyi yükleyip döndürebilir. Aşağıdaki listede bazı örnek senaryolar açıklanmaktadır.
İşleyici, derlemenin bir sürümünün konumunu biliyorsa, derlemeyi Assembly.LoadFrom veya Assembly.LoadFile yöntemini kullanarak yükleyebilir ve başarılı olursa yüklenen derlemeyi döndürebilir.
İşleyicinin bayt dizileri olarak depolanan bir derleme veritabanına erişimi varsa, bayt dizisi alan yöntem aşırı yüklemelerinden Assembly.Load birini kullanarak bayt dizisini yükleyebilir.
İşleyici dinamik bir derleme oluşturabilir ve döndürebilir.
Uyarı
İşleyici, derlemeyi yükleme bağlamına, load-from bağlamına veya bağlam olmadan yüklemelidir. İşleyici, Assembly.ReflectionOnlyLoad veya Assembly.ReflectionOnlyLoadFrom yöntemini kullanarak derlemeyi yalnızca yansıma bağlamı içine yüklerse, AssemblyResolve olayını tetikleyen yükleme girişimi başarısız olur.
Uygun bir derleme döndürmek olay işleyicisinin sorumluluğundadır. İşleyici, özellik değerini ResolveEventArgs.Name oluşturucuya geçirerek istenen derlemenin AssemblyName(String) görünen adını ayrıştırabilir. .NET Framework 4'le başlayarak işleyici, geçerli isteğin ResolveEventArgs.RequestingAssembly başka bir derlemenin bağımlılığı olup olmadığını belirlemek için özelliğini kullanabilir. Bu bilgiler, bağımlılığı karşılayan bir derlemenin tanımlanmasına yardımcı olabilir.
Olay işleyicisi, derlemenin istenen sürümden farklı bir sürümünü döndürebilir.
Çoğu durumda, işleyici tarafından döndürülen derleme, işleyicinin yüklediği bağlamdan bağımsız olarak yük bağlamında görünür. Örneğin, işleyici bir derlemeyi yükleme bağlamına yüklemek için Assembly.LoadFrom yöntemini kullanıyorsa, işleyici onu geri döndürdüğünde derleme yükleme bağlamında görünür. Ancak, aşağıdaki durumda işleyici onu döndürdüğünde derleme bağlam olmadan görünür:
İşleyici bağlam olmadan bir derleme yükler.
ResolveEventArgs.RequestingAssembly Özelliği null değil.
İstekte bulunan derleme (yani ResolveEventArgs.RequestingAssembly Özelliği tarafından döndürülen derleme) bağlam olmadan yüklendi.
Bağlamlar hakkında bilgi için Assembly.LoadFrom(String) yönteminin aşırı yüklemeleri kısmına bakın.
Aynı derlemenin birden çok sürümü aynı uygulama etki alanına yüklenebilir. Tür atama sorunlarına neden olabileceği için bu uygulama önerilmez. Bkz. Derleme yükleme için en iyi yöntemler.
Olay işleyicisinin yapmaması gerekenler
Olayı işlemeye yönelik AssemblyResolve birincil kural, tanımadığınız bir derlemeyi döndürmeyi denememektir. İşleyiciyi yazarken, hangi derlemelerin olayın tetiklenmesine neden olabileceğini bilmelisiniz. İşleyiciniz diğer derlemeler için null döndürmelidir.
Önemli
.NET Framework 4'le başlayarak, AssemblyResolve olay uydu derlemeleri için tetiklenir. İşleyici tüm derleme yük isteklerini çözümlemeye çalışırsa, bu değişiklik .NET Framework'ün önceki bir sürümü için yazılmış bir olay işleyicisini etkiler. Tanımadıkları derlemeleri yoksayan olay işleyicileri bu değişiklikten etkilenmez: null döndürür ve normal geri dönüş mekanizmaları devreye girer.
Bir derlemeyi yüklerken, olay işleyicisi AppDomain.Load olayını özyinelemeli bir şekilde tetikleyebilecek Assembly.Load veya AssemblyResolve yöntem aşırı yüklemelerinden hiçbirini kullanmamalıdır, çünkü bu bir yığın taşmasına neden olabilir. (Bu konunun önceki bölümlerinde sağlanan listeye bakın.) Tüm olay işleyicileri dönene kadar hiçbir özel durum atılmadığından, yük isteği için özel durum işleme sağlasanız bile bu durum oluşur. Bu nedenle, MyAssembly bulunmadığı takdirde aşağıdaki kod yığın taşmasına yol açar:
using System;
using System.Reflection;
class BadExample
{
static void Main()
{
AppDomain ad = AppDomain.CreateDomain("Test");
ad.AssemblyResolve += MyHandler;
try
{
object obj = ad.CreateInstanceAndUnwrap(
"MyAssembly, version=1.2.3.4, culture=neutral, publicKeyToken=null",
"MyType");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static Assembly MyHandler(object source, ResolveEventArgs e)
{
Console.WriteLine("Resolving {0}", e.Name);
// DO NOT DO THIS: This causes a StackOverflowException
return Assembly.Load(e.Name);
}
}
/* This example produces output similar to the following:
Resolving MyAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null
Resolving MyAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null
...
Resolving MyAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null
Resolving MyAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null
Process is terminated due to StackOverflowException.
*/
Imports System.Reflection
Class BadExample
Shared Sub Main()
Dim ad As AppDomain = AppDomain.CreateDomain("Test")
AddHandler ad.AssemblyResolve, AddressOf MyHandler
Try
Dim obj As object = ad.CreateInstanceAndUnwrap(
"MyAssembly, version=1.2.3.4, culture=neutral, publicKeyToken=null",
"MyType")
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Sub
Shared Function MyHandler(ByVal source As Object, _
ByVal e As ResolveEventArgs) As Assembly
Console.WriteLine("Resolving {0}", e.Name)
// DO NOT DO THIS: This causes a StackOverflowException
Return Assembly.Load(e.Name)
End Function
End Class
' This example produces output similar to the following:
'
'Resolving MyAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null
'Resolving MyAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null
'...
'Resolving MyAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null
'Resolving MyAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null
'
'Process is terminated due to StackOverflowException.
using namespace System;
using namespace System::Reflection;
ref class Example
{
internal:
static Assembly^ MyHandler(Object^ source, ResolveEventArgs^ e)
{
Console::WriteLine("Resolving {0}", e->Name);
// DO NOT DO THIS: This causes a StackOverflowException
return Assembly::Load(e->Name);
}
};
void main()
{
AppDomain^ ad = AppDomain::CreateDomain("Test");
ad->AssemblyResolve += gcnew ResolveEventHandler(&Example::MyHandler);
try
{
Object^ obj = ad->CreateInstanceAndUnwrap(
"MyAssembly, version=1.2.3.4, culture=neutral, publicKeyToken=null",
"MyType");
}
catch (Exception^ ex)
{
Console::WriteLine(ex->Message);
}
}
/* This example produces output similar to the following:
Resolving MyAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null
Resolving MyAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null
...
Resolving MyAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null
Resolving MyAssembly, Version=1.2.3.4, Culture=neutral, PublicKeyToken=null
Process is terminated due to StackOverflowException.
*/
AssemblyResolve'ı işlemenin doğru yolu
Olay işleyicisinden AssemblyResolve derlemeleri çözümlerken, işleyici StackOverflowException veya Assembly.Load yöntemini çağırırsa, sonunda bir AppDomain.Load atılır. Bunun yerine, LoadFile olayı tetiklemeyen LoadFrom veya AssemblyResolve yöntemlerini kullanın.
Yürütme derlemesinin yakınında, bilinen bir konumda yer alan MyAssembly.dll'yı hayal edin; derlemenin yolu verildiğinde Assembly.LoadFile kullanılarak çözümlenebilir.
using System;
using System.IO;
using System.Reflection;
class CorrectExample
{
static void Main()
{
AppDomain ad = AppDomain.CreateDomain("Test");
ad.AssemblyResolve += MyHandler;
try
{
object obj = ad.CreateInstanceAndUnwrap(
"MyAssembly, version=1.2.3.4, culture=neutral, publicKeyToken=null",
"MyType");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
static Assembly MyHandler(object source, ResolveEventArgs e)
{
Console.WriteLine("Resolving {0}", e.Name);
var path = Path.GetFullPath("../../MyAssembly.dll");
return Assembly.LoadFile(path);
}
}
Imports System.IO
Imports System.Reflection
Class CorrectExample
Shared Sub Main()
Dim ad As AppDomain = AppDomain.CreateDomain("Test")
AddHandler ad.AssemblyResolve, AddressOf MyHandler
Try
Dim obj As Object = ad.CreateInstanceAndUnwrap(
"MyAssembly, version=1.2.3.4, culture=neutral, publicKeyToken=null",
"MyType")
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Sub
Shared Function MyHandler(ByVal source As Object,
ByVal e As ResolveEventArgs) As Assembly
Console.WriteLine("Resolving {0}", e.Name)
Dim fullPath = Path.GetFullPath("../../MyAssembly.dll")
Return Assembly.LoadFile(fullPath)
End Function
End Class
using namespace System;
using namespace System::IO;
using namespace System::Reflection;
ref class Example
{
internal:
static Assembly^ MyHandler(Object^ source, ResolveEventArgs^ e)
{
Console::WriteLine("Resolving {0}", e->Name);
String^ fullPath = Path::GetFullPath("../../MyAssembly.dll");
return Assembly::LoadFile(fullPath);
}
};
void main()
{
AppDomain^ ad = AppDomain::CreateDomain("Test");
ad->AssemblyResolve += gcnew ResolveEventHandler(&Example::MyHandler);
try
{
Object^ obj = ad->CreateInstanceAndUnwrap(
"MyAssembly, version=1.2.3.4, culture=neutral, publicKeyToken=null",
"MyType");
}
catch (Exception^ ex)
{
Console::WriteLine(ex->Message);
}
}