Programing

Visual Studio에서 어셈블리 참조의 "특정 버전"속성은 정확히 어떻게 작동합니까?

crosscheck 2020. 6. 22. 07:59
반응형

Visual Studio에서 어셈블리 참조의 "특정 버전"속성은 정확히 어떻게 작동합니까?


오늘은 Visual Studio 2010에서 어셈블리 참조의 "특정 버전"속성에 대해 자세히 살펴 보았습니다. 예기치 않은 결과를 몇 차례 실험 한 후 속성 작동 방식에 대해 가능한 많이 배우기 시작했습니다. 그렇더라도 나에게 나타나고 모든 대답이없는 것이므로 여기에 질문에 스스로 대답하려고합니다.

Visual Studio에서 어셈블리 참조의 "특정 버전"속성은 정확히 어떻게 작동합니까?


컴파일 타임 속성입니다!

알아야 할 가장 중요한 사항 중 하나는 "특정 버전"에 적용됩니다 속성이라는 것이다 컴파일 시간하지 런타임에 있습니다.

무엇에 관한 것입니까?

프로젝트를 빌드 할 때 빌드 시스템이 사용해야하는 실제 어셈블리를 찾으려면 프로젝트의 어셈블리 참조를 확인해야합니다. "특정 버전"검사가 수행되면 ( "특정 버전"은 언제 점검됩니까? "섹션 참조) 조립 해결 프로세스의 결과에 영향을줍니다.

  • 빌드 시스템은 잠재적으로 사용할 수있는 물리적 어셈블리를 찾습니다
  • 빌드 시스템은 실제 어셈블리 버전을 어셈블리 참조를 위해 .csproj 파일에 저장된 어셈블리 버전과 비교합니다.
  • 두 어셈블리 버전이 정확히 동일한 경우 해결 프로세스가 성공하고 발견 된 실제 어셈블리가 빌드에 사용됩니다.
  • 두 어셈블리 버전이 일치하지 않으면 물리적 어셈블리가 삭제되고 다음 잠재적 어셈블리를 찾아 해결 프로세스가 계속됩니다.
  • 더 이상 잠재적 인 물리적 어셈블리를 찾을 수 없으면 해결 프로세스가 실패합니다. 이로 인해 참조를 해결할 수 없다는 컴파일러 경고 (경고 MSB3245)가 발생합니다.
  • 흥미롭게도 빌드가 계속됩니다! 코드에 어셈블리에 대한 실제 참조가 없으면 빌드가 완료됩니다 (이전에 언급 된 경고와 함께). 코드에 참조가 있으면 코드에서 알 수없는 형식이나 네임 스페이스를 사용하는 것처럼 보이는 오류와 함께 빌드가 실패합니다. 빌드가 실제로 실패한 유일한 이유 는 경고 MSB3245입니다.

어셈블리가 해결되는 순서

어셈블리 해결 프로세스가 잠재적 어셈블리를 찾는 순서는 다음과 같습니다.

  1. <HintPath>.csproj 파일 요소가 참조하는 어셈블리
  2. 프로젝트 출력 경로
  3. GAC

GAC에 여러 버전의 어셈블리가있는 경우 해결 프로세스는 먼저 가장 높은 버전의 어셈블리로 해석하려고 시도합니다. "특정 버전"검사를하지 않은 경우에만 중요합니다.

"특정 버전"은 언제 확인됩니까?

Visual Studio는 .csproj 파일에있는 두 가지 정보를 기반으로 "특정 버전"검사를 수행할지 여부를 결정합니다.

  • <SpecificVersion>요소의 유무 및 가치 (존재하는 경우)
  • 조립품 참조에 버전 정보의 유무

버전 정보가있는 일반적인 어셈블리 참조는 다음과 같습니다.

<Reference Include="Foo, Version=1.2.3.4, Culture=neutral, processorArchitecture=MSIL">
  <SpecificVersion>True</SpecificVersion>
  <HintPath>..\..\Bar\Foo.dll</HintPath>
</Reference>

버전 정보가 없는 어셈블리 참조 모양은 다음과 같습니다 .

<Reference Include="Foo">
[...]

다음 표는 "특정 버전"검사가 수행 된시기와 그렇지 않은 경우를 보여줍니다.

                            |     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)

여기서 놀라운 점은 <SpecificVersion>버전 정보와 버전 정보가 모두 없으면 검사가 수행되지 않는다는 것입니다 (사례 6). 나는 이해가 없으면 <SpecificVersion>기본값 "True" 의미 하기 때문에 검사가 수행되고 항상 실패 할 것으로 예상했을 것입니다 (사례 2와 동일) . 이것은 테스트를 수행 한 Visual Studio 2010의 단점 일 수 있습니다.

Visual Studio UI에서 어셈블리 참조의 속성을 검사 할 때 (참조를 선택하고 F4를 누름) "Specific Version"속성에 표시되는 값은 Visual Studio가 "Specific Version"을 수행할지 여부를 알려줍니다. 검사. 6의 경우 <SpecificVersion>요소가 .csproj 파일에 없지만 UI에 "True"가 표시 됩니다.

"로컬 복사"에 대한 부작용

"로컬 복사"속성이 "참"으로 설정되어 있지만 "특정 버전"확인으로 인해 어셈블리 해결 프로세스가 실패하면 어셈블리가 복사되지 않습니다.

참고 자료


참조를 추가하면 Visual Studio는 프로젝트 파일에 어셈블리의 [AssemblyVersion]을 기록합니다. 이건 중요하다. 예를 들어, 1 년 후 버그 수정을 작성한 경우 정확히 동일한 버전의 참조로 프로젝트를 다시 빌드해야합니다 . 참조 어셈블리가 변경되면 오류가 발생합니다.

But that isn't always desirable. Some programmers let the assembly version automatically increment, generating a new version every single time they rebuild. Even though the public interface of the assembly never changed. Some configure their project by using Nuget to obtain libraries and let it automatically update the library when there's a new release available. They will like to set the Specific Version property to False to suppress the compile error.

Pretty important to understand the consequence, you do need to redeploy the entire build of the program to avoid accidents. Version mismatches at runtime crash the program and can only be suppressed with a <bindingRedirect> in the .config file which is risky.

참고URL : https://stackoverflow.com/questions/24022134/how-exactly-does-the-specific-version-property-of-an-assembly-reference-work-i

반응형