Aracılığıyla paylaş


Bileşen Yükleme için En İyi Uygulamalar

Uyarı

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, InvalidCastException, MissingMethodException ve diğer hatalara yol açabilecek kimlik türü 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 uygulama etki alanının ApplicationBase ve PrivateBinPath öğelerini içerir. Çoğu Load yöntemi aşırı yükleme derlemeleri bu bağlamda yükler.

  • Yükleyicinin aramadığı konumlardan yüklenen derlemeler yükleme bağlamını oluşturur. Ö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ı, ReflectionOnlyLoad ve ReflectionOnlyLoadFrom yöntemleriyle 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 Reflection-Only Bağlamı'na Yükleme.

  • Yansıma yayma kullanarak geçici bir dinamik derleme oluşturduysanız, derleme herhangi bir bağlamda yer almaz. 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ına yüklenen bağımlılıklar, varsayılan yük bağlamındaki veya yükleme-kaynak 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 erişilebilir değildir.

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

Load-From 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 LoadFrom yüklenirse ve daha sonra varsayılan yük bağlamındaki bir derleme aynı derlemeyi görünen adla yüklemeye çalışırsa, yükleme girişimi başarısız olur. Bir modül seri durumdan çıkarıldığında bu durum oluşabilir.

  • Bir derleme LoadFrom ile yüklendiyse ve yoklama yolu aynı kimliğe sahip ancak farklı bir konumda bir derleme içeriyorsa, bir InvalidCastException, MissingMethodException veya başka bir beklenmeyen davranış oluşabilir.

  • LoadFrom talep eder FileIOPermissionAccess.Read ve FileIOPermissionAccess.PathDiscovery, 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, AppDomain.AssemblyResolve olayını işlemediğiniz sürece bağlam olmadan yüklenen derlemelere bağlanamaz.

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

  • Bağlam olmadan aynı kimliğe sahip birden çok derleme yüklemek, birden çok bağlama aynı kimliğe sahip derlemeleri yüklemenin neden olduğu tür kimliği sorunlarına benzer sorunlara neden olabilir. Bkz. Bir Derlemeyi Birden Fazla Kontekste Yüklemekten Kaçının.

  • 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ı Kullanırken Bağlama İşleminden 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, sürüm, kültür ve ortak anahtar belirtecini atlayarak yöntemi yalnızca derlemenin basit adıyla Assembly.Load çağırabilirsiniz. Veya Assembly.LoadWithPartialName yöntemini çağırabilir ve bu yöntem ilk olarak Assembly.Load yöntemini çağırır, eğer bu derlemeyi bulamazsa, genel derleme önbelleğini tarar 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:

  • Assembly.LoadWithPartialName metodu aynı basit ada sahip bir başka derlemeyi 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 Assembly.Load yöntemini kullanmanızı ve tam derleme görüntüleme 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ğlamda Yüklemekten Kaçının

Bir derlemeyi birden çok bağlama yüklemek tip kimliği sorunlarına neden olabilir. Aynı tür aynı derlemeden iki farklı bağlama yüklenirse, iki farklı tür aynı adla yüklenmiş gibi olur. Bir InvalidCastException atılır, türü diğerine dönüştürmeye çalışırsanız, türün MyType'den MyType'ye dönüştürülemeyeceği kafa karıştırıcı bir iletiyle.

Örneğin, ICommunicate arabirimi, programınız ve programınızın yüklediği diğer derlemeler tarafından başvurulan Utility adlı derlemede 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, LoadFile yöntemini kullanarak hedef derlemeyi dosya yoluna göre yüklerseniz, varsayın. 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 AppDomain.AssemblyResolve olayı için bir işleyiciniz olabilir ve Utility derlemesini LoadFile yöntemini kullanarak bağlam olmadan yükleyebilir. Hedef derlemede bulunan bir türün örneğini oluşturduğunuzda ve türü ICommunicate olan bir değişkene atamaya çalıştığınızda, çalışma zamanı InvalidCastException derlemesinin iki kopyasındaki ICommunicate arabirimlerini farklı türler olarak değerlendirdiğinden bir Utility fırlatılır.

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 Load yöntemini tam görünen adıyla kullanarak ç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, onu yük-bağlamına yüklemek için LoadFrom yöntemini kullanabilirsiniz. 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 Utility derlemesini yüklemeden önce yük bağlamına 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ü, LoadFile ve LoadFrom gibi dosya yolu yüklemelerine alternatifleri açıklar.

Bütünleştirilmiş Paketin Birden Çok Sürümünü Aynı Ortama 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 atılır, türü diğerine dönüştürmeye çalışırsanız, türün MyType'den MyType'ye dönüştürülemeyeceği kafa karıştırıcı bir iletiyle.

Örneğin, programınız doğrudan Utility derlemesinin bir sürümünü yükleyebilir ve daha sonra Utility derlemesinin farklı bir sürümünü 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, Assembly.Load yöntemini kullandığınızda ve farklı sürüm numaraları içeren tam derleme görüntü adlarını belirttiğinizde 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öntemin kullanılmasını bekleyebilir.

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 Add-In 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 AppDomainSetup.ApplicationBase özelliğini kullanın. 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 ApplicationBase derlemeleri için uygun yola ayarlayabilirsiniz.

Assembly.LoadFrom yöntemini kullanarak bu derlemeleri yükleyebileceğinizi unutmayın. Artık yoklama yolunda oldukları için, yükleme-yük bağlamı yerine varsayılan yük bağlamına yüklenecekler. Ancak, her zaman doğru sürümlerin kullanıldığından emin olmak için Assembly.Load yöntemine geçmenizi ve tam bütünleştirilmiş gösterim adları sağlamanızı öneririz.

Ayrıca bakınız