Derleme Yükleme için En İyi Yöntemler

Not

Bu makale .NET Framework'e özgüdür. .NET 6 ve sonraki sürümleri de dahil olmak üzere daha yeni .NET uygulamaları için geçerli değildir.

Bu makalede, MissingMethodExceptionve diğer hatalara yol açabilecek InvalidCastExceptiontür kimliği sorunlarını önlemenin yolları açıklanır. Makalede aşağıdaki öneriler ele alınmaktadır:

İlk öneri, yük bağlamlarının avantajlarını ve dezavantajlarını anlamak, diğer öneriler için arka plan bilgileri sağlar, çünkü bunların tümü yük bağlamları hakkında bir bilgiye bağlıdır.

Yük Bağlamlarının Avantajlarını ve Dezavantajlarını Anlama

Uygulama etki alanında derlemeler üç bağlamdan birine yüklenebilir veya bağlam olmadan yüklenebilir:

  • Varsayılan yük bağlamı, genel derleme önbelleğinin yoklanmasıyla bulunan derlemeleri, çalışma zamanı barındırılıyorsa konak derleme deposunu (örneğin, SQL Server'da) ve ApplicationBase uygulama etki alanının ve PrivateBinPath öğelerini içerir. Yöntemin Load çoğu aşırı yükleme derlemelerini bu bağlama yükler.

  • Yükten yükleme bağlamı, yükleyici tarafından aranmayan konumlardan yüklenen derlemeleri içerir. Örneğin, eklentiler uygulama yolunun altında olmayan bir dizine yüklenebilir. Assembly.LoadFrom, AppDomain.CreateInstanceFromve AppDomain.ExecuteAssembly yol ile yüklenen yöntemlere örnektir.

  • Yalnızca yansıma bağlamı ve ReflectionOnlyLoadFrom yöntemleriyle ReflectionOnlyLoad yüklenen derlemeleri içerir. Bu bağlamdaki kod yürütülemez, bu nedenle burada tartışılmaz. Daha fazla bilgi için bkz . Nasıl yapılır: Derlemeleri Yalnızca Yansıma Bağlamı'na Yükleme.

  • Yansıma yayma kullanarak geçici bir dinamik derleme oluşturduysanız, derleme herhangi bir bağlamda değildir. Ayrıca, yöntemi kullanılarak LoadFile yüklenen derlemelerin çoğu bağlam olmadan yüklenir ve bayt dizilerinden yüklenen derlemeler, kimlikleri (ilke uygulandıktan sonra) genel derleme önbelleğinde olduklarını belirlemediği sürece bağlam olmadan yüklenir.

Aşağıdaki bölümlerde açıklandığı gibi yürütme bağlamlarının avantajları ve dezavantajları vardır.

Varsayılan Yükleme Bağlamı

Derlemeler varsayılan yük bağlamı içine yüklendiğinde bağımlılıkları otomatik olarak yüklenir. Varsayılan yük bağlamı içine yüklenen bağımlılıklar, varsayılan yük bağlamındaki veya yükleme bağlamındaki derlemeler için otomatik olarak bulunur. Derleme kimliğiyle yükleme, derlemelerin bilinmeyen sürümlerinin kullanılmadığından emin olarak uygulamaların kararlılığını artırır (Kısmi Derleme Adlarında Bağlamayı Önleme bölümüne bakın).

Varsayılan yük bağlamını kullanmanın dezavantajları şunlardır:

  • Diğer bağlamlara yüklenen bağımlılıklar kullanılamaz.

  • Derlemeleri, yoklama yolunun dışındaki konumlardan varsayılan yük bağlamı içine yükleyemezsiniz.

Yük Kaynak Bağlamı

Kaynak yükleme bağlamı, uygulama yolunun altında olmayan ve bu nedenle yoklama işlemine dahil olmayan bir yoldan derleme yüklemenize olanak tanır. Yol bilgileri bağlam tarafından korunacağından, bağımlılıkların bu yoldan konumlandırılıp yüklenmesini sağlar. Ayrıca, bu bağlamdaki derlemeler varsayılan yük bağlamı içine yüklenen bağımlılıkları kullanabilir.

yöntemini veya yola göre yüklenen diğer yöntemlerden birini kullanarak Assembly.LoadFrom derlemeleri yüklemenin aşağıdaki dezavantajları vardır:

  • Aynı kimliğe sahip bir derleme yükleme bağlamında zaten yüklüyse, LoadFrom farklı bir yol belirtilmiş olsa bile yüklenen derlemeyi döndürür.

  • Bir derleme ile LoadFromyüklenirse ve daha sonra varsayılan yük bağlamındaki bir derleme aynı derlemeyi görünen ada göre yüklemeye çalışırsa, yükleme girişimi başarısız olur. Bir derleme seri durumdan çıkarıldığında bu durum oluşabilir.

  • Bir derleme ile LoadFromyüklenirse ve yoklama yolu aynı kimliğe sahip ancak farklı bir konumda bir derleme içeriyorsa, bir , MissingMethodExceptionveya başka bir InvalidCastExceptionbeklenmeyen davranış oluşabilir.

  • LoadFromFileIOPermissionAccess.PathDiscoveryve , FileIOPermissionAccess.Read veya WebPermission, belirtilen yolda.

  • Derleme için yerel bir görüntü varsa, kullanılmaz.

  • Derleme, etki alanı nötr olarak yüklenemez.

  • .NET Framework 1.0 ve 1.1 sürümlerinde ilke uygulanmaz.

Bağlam Yok

Bağlam olmadan yükleme, yansıma yayma ile oluşturulan geçici derlemeler için tek seçenektir. Bağlam olmadan yükleme, aynı kimliğe sahip birden çok derlemeyi tek uygulama etki alanına yüklemenin tek yoludur. Yoklama maliyetinden kaçınılır.

bayt dizilerinden yüklenen derlemeler, ilke uygulandığında oluşturulan derlemenin kimliği genel derleme önbelleğindeki bir derlemenin kimliğiyle eşleşmediği sürece bağlam olmadan yüklenir; bu durumda, derleme genel derleme önbelleğinden yüklenir.

Bağlam olmadan derlemeleri yüklemenin aşağıdaki dezavantajları vardır:

  • Diğer derlemeler, olayı işlemediğiniz AppDomain.AssemblyResolve sürece bağlam olmadan yüklenen derlemelere bağlanamaz.

  • Bağımlılıklar otomatik olarak yüklenmez. Bağlam olmadan bunları önceden yükleyebilir, varsayılan yük bağlamı içine önceden yükleyebilir veya olayı işleyerek AppDomain.AssemblyResolve yükleyebilirsiniz.

  • Bağlam olmadan aynı kimliğe sahip birden çok derlemenin yüklenmesi, aynı kimliğe sahip derlemeleri birden çok bağlama yüklemenin neden olduğu tür kimliği sorunlarına neden olabilir. Bkz. Derlemeyi Birden Çok Bağlama Yüklemekten Kaçınma.

  • Derleme için yerel bir görüntü varsa, kullanılmaz.

  • Derleme, etki alanı nötr olarak yüklenemez.

  • .NET Framework 1.0 ve 1.1 sürümlerinde ilke uygulanmaz.

Kısmi Derleme Adlarında Bağlamadan Kaçının

Derlemeyi yüklediğinizde derleme görünen adının (FullName) yalnızca bir bölümünü belirttiğinizde kısmi ad bağlaması gerçekleşir. Örneğin, yöntemini yalnızca derlemenin basit adıyla çağırabilir Assembly.Load , sürümü, kültürü ve ortak anahtar belirtecini atlayabilirsiniz. Ya da yöntemini çağırabilir ve ilk olarak yöntemini çağırabilir Assembly.LoadWithPartialNameAssembly.Load ve bu, derlemeyi bulamazsa genel derleme önbelleğini arar ve derlemenin en son kullanılabilir sürümünü yükler.

Kısmi ad bağlaması aşağıdakiler de dahil olmak üzere birçok soruna neden olabilir:

  • yöntemi aynı Assembly.LoadWithPartialName basit ada sahip farklı bir derleme yükleyebilir. Örneğin, iki uygulama her ikisi de genel derleme önbelleğine basit adı GraphicsLibrary olan iki tamamen farklı derleme yükleyebilir.

  • Aslında yüklenen derleme geriye dönük olarak uyumlu olmayabilir. Örneğin, sürümün belirtilmemesi, programınızın başlangıçta kullanılmak üzere yazıldığı sürümden çok daha sonraki bir sürümün yüklenmesine neden olabilir. Sonraki sürümdeki değişiklikler uygulamanızda hatalara neden olabilir.

  • Aslında yüklenen derleme ileriye uyumlu olmayabilir. Örneğin, uygulamanızı derlemenin en son sürümüyle oluşturup test etmiş olabilirsiniz, ancak kısmi bağlama, uygulamanızın kullandığı özelliklerden yoksun çok daha eski bir sürümü yükleyebilir.

  • Yeni uygulamaların yüklenmesi mevcut uygulamaları bozabilir. yöntemini kullanan bir uygulama, paylaşılan derlemenin LoadWithPartialName daha yeni, uyumsuz bir sürümü yüklenerek bozulabilir.

  • Beklenmeyen bağımlılık yüklemesi oluşabilir. Bir bağımlılığı paylaşan iki derleme yüklersiniz, bunları kısmi bağlama ile yüklemek, derlenmediği veya test edilmediği bir bileşenin kullanılmasına neden olabilir.

Neden olabileceği sorunlar nedeniyle yöntem LoadWithPartialName kullanım dışı olarak işaretlendi. Bunun yerine yöntemini kullanmanızı Assembly.Load ve tam derleme görünen adlarını belirtmenizi öneririz. Bkz. Yük Bağlamlarının Avantajlarını ve Dezavantajlarını Anlama ve Varsayılan Yük Bağlamı'na Geçmeyi Düşünme.

Derleme yüklemeyi LoadWithPartialName kolaylaştırdığı için yöntemini kullanmak istiyorsanız, uygulamanızın eksik derlemeyi tanımlayan bir hata iletisiyle başarısız olmasını sağlamanın, derlemenin bilinmeyen bir sürümünü otomatik olarak kullanmaktan daha iyi bir kullanıcı deneyimi sağlama olasılığının tahmin edilemez davranışlara ve güvenlik açıklarına neden olabileceğini göz önünde bulundurun.

Derlemeyi Birden Çok Bağlama Yüklemekten Kaçının

Bir derlemeyi birden çok bağlama yüklemek tür kimliği sorunlarına neden olabilir. Aynı tür aynı derlemeden iki farklı bağlama yüklenirse, aynı ada sahip iki farklı tür yüklenmiş gibi olur. Bir InvalidCastException türü diğerine dönüştürmeye çalışırsanız, türün yazılamayacağı MyTypekafa karıştırıcı bir iletiyle MyType oluşturulur.

Örneğin, arabiriminin ICommunicate , programınız ve ayrıca programınızın yüklediği diğer derlemeler tarafından başvurulan adlı Utilityderlemede bildirildiğini varsayalım. Bu diğer derlemeler, arabirimi uygulayan ICommunicate türler içerir ve programınızın bunları kullanmasına olanak sağlar.

Şimdi programınız çalıştırıldığında ne olacağını düşünün. Programınız tarafından başvurulan derlemeler varsayılan yük bağlamı içine yüklenir. Yöntemini kullanarak Load hedef derlemeyi kimliğine göre yüklerseniz, varsayılan yük bağlamında olur ve bağımlılıkları da öyle olur. Hem programınız hem de hedef derlemeniz aynı Utility derlemeyi kullanır.

Ancak, yöntemini kullanarak hedef derlemeyi dosya yoluna göre yüklediğinizden LoadFile emin olun. Derleme herhangi bir bağlam olmadan yüklenir, bu nedenle bağımlılıkları otomatik olarak yüklenmez. Bağımlılığı sağlamak için olay için AppDomain.AssemblyResolve bir işleyiciniz olabilir ve yöntemini kullanarak bağlam olmadan derlemeyi LoadFile yükleyebilirUtility. Şimdi hedef derlemede bulunan bir türün örneğini oluşturduğunuzda ve türündeki ICommunicatebir değişkene atamaya çalıştığınızda, çalışma zamanı derlemenin ICommunicate iki kopyasındaki Utility arabirimleri farklı türler olarak değerlendirdiğinden bir InvalidCastException oluşturulur.

Bir derlemenin birden çok bağlama yüklenebileceği başka birçok senaryo vardır. En iyi yaklaşım, uygulama yolunuzda hedef derlemeyi yeniden konumlandırarak ve yöntemini tam görünen adla kullanarak Load çakışmaları önlemektir. Derleme daha sonra varsayılan yük bağlamı içine yüklenir ve her iki derleme de aynı Utility derlemeyi kullanır.

Hedef derlemenin uygulama yolunuzun dışında kalması gerekiyorsa, yöntemini kullanarak LoadFrom yük bağlama yükleyebilirsiniz. Hedef derleme uygulamanızın Utility derlemesine bir başvuruyla derlenmişse, uygulamanızın Utility varsayılan yük bağlamı içine yüklediği derlemeyi kullanır. Hedef derlemenin uygulama yolunuzun dışında bulunan derlemenin bir kopyasına bağımlılığı varsa sorunlarla karşılaşabileceğinizi Utility unutmayın. Bu derleme, uygulamanız derlemeyi yüklemeden Utility önce yük bağlama yüklenirse, uygulamanızın yükü başarısız olur.

Varsayılan Yük Bağlamı'na Geçmeyi Düşün bölümünde ve LoadFromgibi LoadFile dosya yolu yüklerini kullanmanın alternatifleri açıklanır.

Derlemenin Birden Çok Sürümünü Aynı Bağlama Yüklemekten Kaçının

Bir derlemenin birden çok sürümünün tek bir yük bağlamı içine yüklenmesi tür kimliği sorunlarına neden olabilir. Aynı derlemenin iki sürümünden aynı tür yüklenirse, aynı ada sahip iki farklı tür yüklenmiş gibi olur. Bir InvalidCastException türü diğerine dönüştürmeye çalışırsanız, türün yazılamayacağı MyTypekafa karıştırıcı bir iletiyle MyType oluşturulur.

Örneğin, programınız derlemenin bir sürümünü doğrudan yükleyebilir ve daha sonra derlemenin Utility farklı bir sürümünü Utility yükleyen başka bir derleme yükleyebilir. Veya bir kodlama hatası, uygulamanızda iki farklı kod yolunun bir derlemenin farklı sürümlerini yüklemesine neden olabilir.

Varsayılan yük bağlamında, yöntemini kullandığınızda ve farklı sürüm numaraları içeren tam derleme görünen adlarını belirttiğinizde Assembly.Load bu sorun oluşabilir. Bağlam olmadan yüklenen derlemeler için, farklı yollardan aynı derlemeyi Assembly.LoadFile yüklemek için yönteminin kullanılması soruna neden olabilir. Çalışma zamanı, kimlikleri aynı olsa bile farklı yollardan yüklenen iki derlemeyi farklı derlemeler olarak kabul eder.

Tür kimliği sorunlarına ek olarak, bir derlemenin birden çok sürümü, derlemenin bir sürümünden yüklenen bir türün farklı bir sürümden bu türü bekleyen koda geçirilmesine neden MissingMethodException olabilir. Örneğin, kod sonraki sürüme eklenmiş bir yöntem bekleyebilirsiniz.

Türün davranışı sürümler arasında değiştiğinde daha ince hatalar oluşabilir. Örneğin, bir yöntem beklenmeyen bir özel durum oluşturabilir veya beklenmeyen bir değer döndürebilir.

Derlemenin yalnızca bir sürümünün yüklendiğinden emin olmak için kodunuzu dikkatle gözden geçirin. Herhangi bir zamanda hangi derlemelerin yüklendiğini belirlemek için yöntemini kullanabilirsiniz AppDomain.GetAssemblies .

Varsayılan Yükleme Bağlamı'na geçmeyi göz önünde bulundurun

Uygulamanızın derleme yükleme ve dağıtım desenlerini inceleyin. Bayt dizilerinden yüklenen derlemeleri ortadan kaldırabilir misiniz? Derlemeleri yoklama yoluna taşıyabilir misiniz? Derlemeler genel derleme önbelleğinde veya uygulama etki alanının yoklama yolunda (yani, onun ApplicationBase ve PrivateBinPath) bulunuyorsa, derlemeyi kimliğine göre yükleyebilirsiniz.

Tüm derlemelerinizi yoklama yoluna koymak mümkün değilse, .NET Framework eklenti modelini kullanma, derlemeleri genel derleme önbelleğine yerleştirme veya uygulama etki alanları oluşturma gibi alternatifleri göz önünde bulundurun.

.NET Framework Eklenti Modelini Kullanmayı Düşünün

Normalde uygulama tabanında yüklü olmayan eklentileri uygulamak için kaynak bağlamını kullanıyorsanız. .NET Framework eklenti modelini kullanın. Bu model, uygulama etki alanlarını kendiniz yönetmenize gerek kalmadan uygulama etki alanında veya işlem düzeyinde yalıtım sağlar. Eklenti modeli hakkında bilgi için bkz . Eklentiler ve Genişletilebilirlik.

Genel Bütünleştirilmiş Kod Önbelleğini Kullanmayı Düşünün

Varsayılan yük bağlamının avantajlarını kaybetmeden veya diğer bağlamların dezavantajlarını üstlenmeden uygulama tabanının dışındaki paylaşılan bir derleme yolundan yararlanmak için derlemeleri genel derleme önbelleğine yerleştirin.

Uygulama Etki Alanlarını Kullanmayı Düşünün

Bazı derlemelerinizin uygulamanın yoklama yolunda dağıtılamayacağını belirlerseniz, bu derlemeler için yeni bir uygulama etki alanı oluşturmayı göz önünde bulundurun. Yeni uygulama etki alanını oluşturmak için bir AppDomainSetup kullanın ve yüklemek istediğiniz derlemeleri içeren yolu belirtmek için özelliğini kullanın AppDomainSetup.ApplicationBase . Yoklamanız gereken birden çok dizin varsa, öğesini bir kök dizin olarak ayarlayabilir ApplicationBase ve yoklama alt dizinlerini tanımlamak için özelliğini kullanabilirsiniz AppDomainSetup.PrivateBinPath . Alternatif olarak, birden çok uygulama etki alanı oluşturabilir ve her bir uygulama etki alanının derlemeleri için uygun yola ayarlayabilirsiniz ApplicationBase .

Bu derlemeleri yüklemek için yöntemini kullanabileceğinizi Assembly.LoadFrom unutmayın. Artık yoklama yolunda olduklarından, yükten yükleme bağlamı yerine varsayılan yük bağlamı içine yüklenirler. Ancak, doğru sürümlerin her zaman kullanıldığından Assembly.Load emin olmak için yöntemine geçmenizi ve tam bütünleştirilmiş kod görünen adları sağlamanızı öneririz.

Ayrıca bkz.