.NET 4.0'da yeni bir GAC var, neden?


300

%windir%\Microsoft.NET\assembly\yeni GAC . Şimdi biri .NET 2.0-3.5 uygulamaları diğeri .NET 4.0 uygulamaları için olmak üzere iki GAC'yi yönetmemiz gerektiği anlamına mı geliyor?

Soru, neden?


7
soruyu sorduğunuz için teşekkür ederim ... ben orijinal konumunda gac bulamadık da çok
karışıkım

2
Güzel soru ... Çok teşekkürler.
smwikipedia

1
Sorunuz için +1. NET 4.0 altında geliştirmeye başladım ve "ikili" GAC sorunu ile karıştırdım.
Hernán

3
Birkaç yineleme aldı, ancak Microsoft nihayet DLL Hell'i .NET'e getirdi. Yaşasın!
15:23 de gereksiz

Yanıtlar:


181

Evet, 2 ayrı Global Assembly Cache (GAC) olduğundan, her birini ayrı ayrı yönetmeniz gerekecek.

.NET Framework 4.0'da GAC ​​birkaç değişiklik geçirdi. GAC, her CLR için bir olmak üzere ikiye ayrıldı.

Hem .NET Framework 2.0 hem de .NET Framework 3.5 için kullanılan CLR sürümü CLR 2.0'dır. Önceki iki çerçeve bülteninde GAC'ın bölünmesine gerek yoktu. Net Framework 4.0'da eski uygulamaları bozma sorunu.

CLR 2.0 ve CLR 4.0 arasındaki sorunları önlemek için, GAC artık her çalışma zamanı için özel GAC'lara ayrılmıştır.Ana değişiklik CLR v2.0 uygulamalarının artık GAC'de CLR v4.0 derlemelerini görememesidir.

Kaynak

Neden?

.NET 4.0'da bir CLR değişikliği olduğu, ancak 2.0'dan 3.5'e olmadığı için görünüyor. Aynı şey 1.1 ila 2.0 CLR için de oldu. GAC, aynı CLR'den olduğu sürece farklı montaj sürümlerini saklama yeteneğine sahip gibi görünüyor. Eski uygulamaları kırmak istemiyorlar.

4.0'daki GAC değişiklikleri hakkında MSDN'deki aşağıdaki bilgilere bakın .

Örneğin, hem .NET 1.1 hem de .NET 2.0 aynı GAC'yi paylaştıysa, bu paylaşılan GAC'den bir derleme yükleyen bir .NET 1.1 uygulaması .NET 2.0 derlemelerini alabilir ve böylece .NET 1.1 uygulamasını kırabilir

Hem .NET Framework 2.0 hem de .NET Framework 3.5 için kullanılan CLR sürümü CLR 2.0'dır. Bunun sonucu olarak, önceki iki çerçeve bülteninde GAC'ın bölünmesine gerek yoktu. Daha eski (bu durumda .NET 2.0) uygulamaların kırılması sorunu Net Framework 4.0'da yeniden ortaya çıkar ve bu noktada CLR 4.0 yayımlanır. Bu nedenle, CLR 2.0 ve CLR 4.0 arasındaki parazit sorunlarından kaçınmak için GAC artık her çalışma zamanı için özel GAC'lara ayrılmıştır.

CLR gelecekteki sürümlerde güncellendiğinden, aynı şeyi bekleyebilirsiniz. Yalnızca dil değişirse aynı GAC'yi kullanabilirsiniz.


18
Bu blog yazısı yalnızca OP'nin keşfini yeniden ifade ediyor, GAC'nin neden bölünmesi gerektiğini açıklamıyor . Açıkça görülüyor ki, orijinal GAC 4.0 derlemelerini ayrı tutabilecekti. Yeni bir [AssemblyVersion] var
Hans Passant

1
@Hans: Belki de tam nedeni değil ama şöyle diyor: "CLR 2.0 ve CLR 4.0 arasındaki sorunları önlemek için", ayrıca sorunun içinde 2 soru vardı. İkinci soru şudur: "şimdi biri .NET 2.0-3.5 uygulamaları için diğeri .NET 4.0 uygulamaları için olmak üzere iki GAC'yi yönetmemiz gerektiği anlamına mı geliyor?"
Brian R. Bondy

2
Bunu bağlantılarınızdan birinden alıntılamanız gerekir: Örneğin, hem .NET 1.1 hem de .NET 2.0 aynı GAC'yi paylaştıysa, bu paylaşılan GAC'den bir derleme yükleyen bir .NET 1.1 uygulaması .NET 2.0 derlemelerini alabilir , böylece .NET 1.1 uygulamasını bozar. "
Max Toro

67

Ben de neden 2 GAC öğrenmek istedi ve şu buldum Mark Miller tarafından açıklama içinde yorum bölümünde bir .NET 4.0 sahiptir 2 genel birleştirme önbelleği (GAC) :

Mark Miller dedi ki ... 28 Haziran 2010 12:13

Gönderi için teşekkürler. "Müdahale sorunları" kasıtlı olarak belirsizdi. Yazım sırasında, sorunlar hala araştırılmaktadır, ancak birkaç kırık senaryo olduğu açıktı.

Örneğin, bazı uygulamalar bir montajın en yüksek sürümünü yüklemek için Assemby.LoadWithPartialName kullanır. En yüksek sürüm v4 ile derlenmişse, bir v2 (3.0 veya 3.5) uygulaması onu yükleyemedi ve çalışacak bir sürüm olsa bile uygulama çökecekti. Başlangıçta, GAC'ı orijinal konumu altında bölümledik, ancak bu, Windows yükseltme senaryolarında bazı sorunlara neden oldu. Bunların her ikisi de zaten gönderilen kodu içeriyordu, bu yüzden (sürüm bölümlü GAC'ımızı başka bir yere taşıdık.

Bunun çoğu uygulama üzerinde herhangi bir etkisi olmamalı ve herhangi bir bakım yükü getirmez. Her iki konuma da yalnızca bölümleme ile beklendiği gibi ilgilenen yerel GAC API'leri kullanılarak erişilmeli veya değiştirilmelidir. Bunun yüzeye çıktığı yerler, GetCachePath gibi GAC yollarını gösteren veya yönetilen koda yüklenen mscorlib yolunu inceleyen API'lerdir.

Montaj kimliğinin bir parçası olarak mimariyi tanıttığımızda, v2'yi piyasaya sürdüğümüzde GAC konumlarını değiştirdiğimizi belirtmek gerekir. Bunların tümü hala% windir% \ assembly altında olsa da GAC_MSIL, GAC_32 ve GAC_64 ekledi. Ne yazık ki, bu sürüm için bir seçenek değildi.

Umarım gelecekteki okuyuculara yardımcı olur.


3
Miller'in bağlantılı makale hakkındaki yorumları, konuya bir içeriden bakış sağlar.
Nimesh Madhavan

66

Çok mantıklı değil, orijinal GAC zaten farklı montaj versiyonlarını saklayabiliyordu. Ve bir programın yanlışlıkla yanlışlıkla derlemeye başvuracağını varsaymak için çok az neden var, tüm .NET 4 derlemeleri [AssemblyVersion] 'u 4.0.0.0'a kadar yükseltti. Yeni işlem içi yan yana özellik bunu değiştirmemelidir.

Benim tahminim: "GAC'da hiçbir şeye doğrudan başvurma" kuralını bozan çok fazla .NET projesi vardı. Bu sitede birkaç kez yapıldığını gördüm.

Bu projeleri kırmaktan kaçınmanın tek yolu: GAC'ı taşımak. Geri uyumluluk Microsoft'ta kutsaldır.


3
Bunun neden böyle olduğunu açıklamaya çalışan tek cevap bu . +1
Ed

1
@Hans Passant: "GAC'da asla hiçbir şeye doğrudan gönderme" kuralı ile ne demek istiyorsun?
Max Toro

2
@ Max: makinenizde iki .NET derlemesi kopyası vardır. Bunlar c: \ windows \ microsoft.net ve c: \ program dosyaları \ başvuru derlemelerinde başvuru derlemeleri anlamına geliyordu. Ve çalışma zamanında kullanılanlar, GAC @ c: \ windows \ assembly. Aynı değiller, 64 bit bir örnek olacaktır. Microsoft, GAC olanlara bir kabuk uzantısı işleyicisi ile başvuran herkesten kaçınmak için ellerinden geleni yaptı. Ve Add Reference iletişim kutusu. % 100 etkili değil
Hans Passant

@Hans Passant: Doğrudan başvuru 'c: \ WINDOWS \ assembly \ GAC_MSIL \ System \ 2.0.0.0__b77a5c561934e089 \ System.dll' gibi bir şey, yeni bir sürüm eklemenin bu başvuruyu nasıl kıracağını görmüyorum.
Max Toro

2
@Hans Passant: "Ve bir programın yanlışlıkla yanlış montajı referans alacağını varsaymak için çok az neden var." Bence buradaki anahtar Assembly.LoadWithPartialName, GAC'de montajın 2 versiyonuna sahipsek ne olur?
Max Toro
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.