To właściwość czasu kompilacji!
Jedną z najważniejszych rzeczy, o których należy wiedzieć, jest to, że „Określona wersja” to właściwość, która obowiązuje w czasie kompilacji, a nie w czasie wykonywania.
O co w tym wszystkim chodzi?
Podczas budowania projektu należy rozwiązać odniesienia do zestawu projektu, aby znaleźć fizyczne zestawy, których powinien używać system kompilacji. Jeśli sprawdzana jest „Określona wersja” (patrz sekcja „Kiedy jest sprawdzana„ Określona wersja ”?”), Ma to wpływ na wynik procesu rozwiązywania zespołu:
- System kompilacji lokalizuje fizyczny zestaw, którego może potencjalnie użyć
- System kompilacji porównuje wersję zestawu fizycznego z wersją zestawu przechowywaną w pliku .csproj dla odwołania do zestawu
- Jeśli dwie wersje zestawu są dokładnie takie same, proces rozwiązywania powiedzie się, a znaleziony zestaw fizyczny jest używany do kompilacji
- Jeśli dwie wersje zestawu nie są zgodne, fizyczny zestaw jest odrzucany, a proces rozwiązywania jest kontynuowany poprzez zlokalizowanie następnego potencjalnego złożenia
- Jeśli nie można zlokalizować więcej potencjalnych zestawów fizycznych, proces rozwiązywania nie powiedzie się. Powoduje to ostrzeżenie kompilatora (ostrzeżenie MSB3245) informujące, że nie można rozwiązać odwołania.
- Co ciekawe, budowa jest kontynuowana! Jeśli kod nie ma rzeczywistych odwołań do zestawu, kompilacja powiedzie się (z wcześniej wspomnianym ostrzeżeniem). Jeśli kod zawiera odwołania, kompilacja kończy się niepowodzeniem z błędem, który wygląda tak, jakby kod używał nieznanych typów lub przestrzeni nazw. Jedyną wskazówką, dlaczego kompilacja naprawdę się nie powiodła, jest ostrzeżenie MSB3245.
Kolejność, w jakiej zespoły są rozwiązywane
Wydaje się, że kolejność, w jakiej proces rozwiązywania zespołu lokalizuje potencjalne zestawy, jest następująca:
- Zestaw, do którego odwołuje się
<HintPath>
element w pliku .csproj
- Ścieżka wyjściowa projektu
- GAC
Należy zauważyć, że jeśli w GAC istnieje kilka wersji zestawu, proces rozpoznawania najpierw próbuje rozwiązać zestaw z najwyższą wersją. Jest to ważne tylko wtedy, gdy nie jest sprawdzana „Określona wersja”.
Kiedy jest zaznaczana „Określona wersja”?
Program Visual Studio opiera swoją decyzję, czy sprawdzić „określoną wersję”, na dwóch informacjach znajdujących się w pliku .csproj:
- Obecność lub brak
<SpecificVersion>
elementu i jego wartość (jeśli występuje)
- Obecność lub brak informacji o wersji w odwołaniu do zestawu
Oto jak wygląda typowe odwołanie do zestawu z informacjami o wersji:
<Reference Include="Foo, Version=1.2.3.4, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>True</SpecificVersion>
<HintPath>..\..\Bar\Foo.dll</HintPath>
</Reference>
A tak wygląda odwołanie do zestawu bez informacji o wersji:
<Reference Include="Foo">
[...]
W poniższej tabeli przedstawiono, kiedy przeprowadzane jest sprawdzenie „określonej wersji”, a kiedy nie.
| Version information
| Present Not present
----------------------------+------------------------------
<SpecificVersion> |
- Present, has value True | Yes (1) Yes (check always fails) (2)
- Present, has value False | No (3) No (4)
- Not present | Yes (5) No (6)
Zaskakujące jest tutaj to, że żadne sprawdzenie nie jest wykonywane, jeśli <SpecificVersion>
nie ma informacji o wersji i wersji (przypadek 6). Spodziewałbym się, że sprawdzenie zostanie wykonane i zawsze zakończy się niepowodzeniem (tak samo jak w przypadku 2), ponieważ w moim rozumieniu brak <SpecificVersion>
implikuje domyślną wartość „True”. Może to być dziwactwo programu Visual Studio 2010, w którym przeprowadzałem testy.
Podczas sprawdzania właściwości odwołania do zestawu w interfejsie użytkownika programu Visual Studio (wybierz odwołanie i naciśnij klawisz F4), wartość widoczna dla właściwości „Określona wersja” informuje, czy program Visual Studio wykona „Określoną wersję” czek. W przypadku 6 interfejs użytkownika pokaże „True”, chociaż <SpecificVersion>
elementu nie ma w pliku .csproj.
Skutki uboczne „Kopiuj lokalnie”
Jeśli właściwość „Kopiuj lokalnie” jest ustawiona na „Prawda”, ale proces rozwiązywania zespołu kończy się niepowodzeniem z powodu sprawdzenia „Określonej wersji”, żaden zestaw nie jest kopiowany.
Materiał referencyjny
PublicKeyToken=
części). Ponadto, jeśli sprawdzisz tabelę pod koniec mojego postu, zobaczysz, że sprawdzanie wersji może nastąpić, nawet jeśliVersion=
brakuje części w nazwie zespołu w .csproj. Pytanie 2: Zakładam, że do porównania używana jest nazwa zespołu, tak. Nie znam żadnego innego źródła informacji.<SpecificVersion>
tag został całkowicie pominięty, który wcześniej miał wartość Fałsz .Po dodaniu odwołania program Visual Studio rejestruje [AssemblyVersion] zestawu w pliku projektu. To jest ważne. Jeśli, powiedzmy, utworzysz naprawę błędu rok później, będziesz chciał się upewnić, że przebudujesz projekt z dokładnie tą samą wersją odniesienia, aby był to prawdziwy drop-in. Otrzymasz błąd, jeśli zestaw referencyjny został zmieniony.
Ale to nie zawsze jest pożądane. Niektórzy programiści pozwalają automatycznie zwiększać wersję zestawu, generując nową wersję za każdym razem, gdy przebudowują. Mimo że publiczny interfejs zestawu nigdy się nie zmienił. Niektórzy konfigurują swój projekt za pomocą Nuget w celu uzyskania bibliotek i pozwalają na automatyczne aktualizowanie biblioteki, gdy jest dostępna nowa wersja. Będą chcieli ustawić właściwość Specific Version na False, aby powstrzymać błąd kompilacji.
Bardzo ważne, aby zrozumieć konsekwencje, musisz ponownie wdrożyć całą kompilację programu, aby uniknąć wypadków. Niezgodność wersji w czasie wykonywania powoduje awarię programu i można ją zlikwidować tylko za pomocą
<bindingRedirect>
znaku w pliku konfiguracyjnym, co jest ryzykowne.źródło
[AssemblyVersion]
gdy zestawy nie są podpisane silną nazwą.