0

I'm currently trying to create a CD pipeline with Azure DevOps with a solution using .NET Framework 4.8 and Oracle. Unfortunately, I can't make it run; as the DLL Oracle.DataAccess is in the GAC, I need to make sure the build-pipeline doesn't package it, otherwise I get the error:

Could not load file or assembly 'Oracle.DataAccess, Version=4.121.19.1, Culture=neutral, PublicKeyToken=89b483f429c47342' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Now, what's interesting: To make it work locally, I have the Oracle.DataAccess DLL copied to a local folder, but reference it with "Copy Local = False":

    <Reference Include="Oracle.DataAccess, Version=4.122.19.1, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=AMD64">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>..\..\librairies\Oracle.DataAccess.dll</HintPath>
      <Private>False</Private>
    </Reference>

Now, when compiling locally, everything is fine and the DLL is not copied locally, but when I build on Azure DevOps, I always get the DLL in the final package and I see the following log-entry:

_CopyFilesMarkedCopyLocal: Copying file from "C:...\19.0.0\client_1\odp.net\bin\4\Oracle.DataAccess.dll" to "Path\bin\Release\Oracle.DataAccess.dll".

The Azure DevOps YAML looking like this:

variables:
  solution: 'src/**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:
...
- task: VSBuild@1
  displayName: 'Build solution'
  inputs:
    solution: '$(solution)'
    vsVersion: '16.0'
    msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
    msbuildArchitecture: 'x64'
    createLogFile: true

Checking with TotalCmd and the likes, I don't see any hidden dependency to the Oracle.DataAccess DLL in the codebase. It seems like the VSBuild Task kinda how wants to copy the file anyway, although me saying it shouldn't. Is there anything I'm not seeing hereby? Or is there a significant difference in how the VSBuild task behaves? I didn't find anything specific in the documentation about such behavior.

Matthias Müller
  • 3,336
  • 3
  • 33
  • 65
  • When the `Oracle.DataAccess` is installed in GAC, then it does not matter if you provide a local copy or not, because the assembly in GAC takes precedence. – Wernfried Domscheit May 13 '22 at 09:07
  • What is installed in GAC, i.e. which version, which architecture (x64 vs. x86) and which policies? Try `gacutil /l | findstr oracle` – Wernfried Domscheit May 13 '22 at 09:17

2 Answers2

1

As workaround you could delete the file manually. Edit your .csproj with a text editor and add this line:

<Target Name="AfterBuild">
  <Delete Files="$(OutputPath)Oracle.DataAccess.dll" />
</Target>

See Extend the Visual Studio build process

Wernfried Domscheit
  • 54,457
  • 9
  • 76
  • 110
  • Thank you very much for the input. It seems like deleting doesn't do the trick, as the Publishing copies it again: "Copying C:\Applications\oracle\product\19.0.0\client_1\odp.net\bin\4\Oracle.DataAccess.dll to obj\Release\Package\PackageTmp\bin\Oracle.DataAccess.dll." Very strange stuff. – Matthias Müller May 13 '22 at 13:37
  • 1
0

I randomly found a solution, but I'm not sure if it's a hack or intended. When I configure the referenced assembly directly in the host assembly like this:

      <Reference Include="Oracle.DataAccess, Version=x.x.x.x, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=AMD64">
          <SpecificVersion>False</SpecificVersion>
          <HintPath>..\..\librairies\Oracle.DataAccess.dll</HintPath>
          <Private>False</Private>
      </Reference>

It works out and the publishing doesn't copy it. I would tend to think this is a bug of the task kinda how, as locally publish doesn't copy the assembly and I would guess, that having a transient dependency with copy=false should honor this as well. Also, having a reference to the data access assembly in the host assembly (like web API) isn't a nice separation of concerns.

Matthias Müller
  • 3,336
  • 3
  • 33
  • 65