6
votes

I have a XCOPY deployable .NET application using Oracle.DataAccess (ODP.NET). We also deploy the Oracle Instant client in the application directory. Everything works OK, but I worry..

From the Oracle ODP.NET FAQ:

Beginning with ODP.NET 10.1.0.3, the Oracle installer will register the following publisher policy DLLs in the Global Assembly Cache (GAC) that redirect 9.2, 10.1 and 10.2 ODP.NET applications to use the last installed version of ODP.NET: Policy.9.2.Oracle.DataAccess.dll and Policy.10.1.Oracle.DataAccess.dll

This means that on machines where the Oracle ODP.NET is installed, the version in the GAC will be used, not the one I deploy with my application. And because of the publisher policy, that version may be newer than the one I deploy with my application. Oracle.DataAccess needs the Oracle (Instant) client also deployed with my application. These are native Win32 DLLs so my version will be used.

Is is possible that Oracle may upgrade the Oracle.DataAccess to a newer version that may not be compatible with the Oracle Instant Client deployed with my application? And thus breaking my application in the future.

Is this a problem? And can I avoid it? Without installing/removing anything on the machine can I override the Oracle Publishers policy to guarantee that I user the Oracle.Dataaccess version that I xcopy deploy with my application?

For a given version of ODP.NET, what Oracle Clients versions does it support? Will new versions of Oracle.DataAccess support old versions of the Oracle (Instant) Client.

4
Oracle has now released a fully managed provider without these problems. oracle.com/technetwork/topics/dotnet/index-085163.htmlArve
Also, the latest version of the Oracle installer now has an option not to put anything in the GAC or machine config.Christian Shay

4 Answers

3
votes

It's possible to force your application to always use the ODP and ODAC version you want.

  1. Force ODP version: use the assemblyBinding trick posted by Robert, to force using your version of Oracle.DataAccess instead of the GAC'd version. E.g.:

    <configuration>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="Oracle.DataAccess"  culture="neutral" publicKeyToken="89b483f429c47342"/>
            <codeBase version="4.112.3.0" href="FILE://Oracle.DataAccess.dll"/>
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
    </configuration>
    
  2. Force ODAC version: The ODP DLL depends on a set of shared Oracle components (instant client, unmanaged OCI dlls). One way to get these is via the ODAC package. You can define (on a per app basis), which ODAC package you want to use. Traditionally this was done via the PATH env variable, but it can now be defined via config:

    <configuration>
      <configSections>
        <section name="oracle.dataaccess.client" type="System.Data.Common.DbProviderConfigurationHandler, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </configSections>
    
      <oracle.dataaccess.client>
        <settings>
          <add name="DllPath" value="C:\somefolder\ODAC_11.2.0.3.0_32bit\bin" />
        </settings>
      </oracle.dataaccess.client>
    </configuration>
    
  3. As an extra precaution, you can always delete the GAC'd publisher policy DLL, to ensure there is never any funky going on.

1
votes

You can use assemblyBinding in the app.config file.

Heres a couple of links that show how to use it.

http://blogs.msdn.com/b/suzcook/archive/2004/05/14/132022.aspx http://stackoverflow.com/questions/1165190/is-there-a-way-to-force-using-a-dll-version

1
votes

I combined Robert & Arve's answer with my previous efforts :

  • Set SpecificVersion to True in the Project's Oracle.DataAccess properties, and make sure the Version stated matches with the version you want to use. If not, manually edit the csproj file to change the version number and delete the copied dll in the bin folder. Visual Studio would automatically find the version number in the GAC. If the version is not yet exist in the GAC, you should install ODAC first.

    <Reference Include="Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86" />

  • Make sure the first OraOps11w.dll found in the Path is the version you want to use. If not, change Windows' System Path so that the directory of the Oracle Client you want to use is the first path entry.

C:\app\user\product\11.1.0\client_1;C:\app\user\product\11.1.0\client_1\bin;other path

  • Disable publisher policy apply in the Web.config or App.config file

  <configuration>
...
     <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
...
            <dependentAssembly>
            <assemblyIdentity name="Oracle.DataAccess"
                                    publicKeyToken="89b483f429c47342"
                                    culture="neutral" />
            <publisherPolicy apply="no"/>
            </dependentAssembly>
        </assemblyBinding>
     </runtime>
  </configuration>

It might be better to close Visual Studio while editing csproj / web.config files in Notepad++ or your favorite text editor. But usually Visual Studio asks you whether you want to reload the project or not.

0
votes

To get Oracle 11 and 12 to play nicely together I had to make the following changes to my app.config file. This is the only change I made, I did not make any changes to my project file such as changing the specific version from false to true.

<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>

  <!--Add This Section to run Oracle 11 and !2 side By Side  -->
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Oracle.DataAccess"  culture="neutral" publicKeyToken="89b483f429c47342"/>
        <codeBase version="4.112.4.0" href="FILE://Oracle.DataAccess.dll"/>
        <publisherPolicy apply="no"/>
      </dependentAssembly>
    </assemblyBinding>

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Oracle.DataAccess"  culture="neutral" publicKeyToken="89b483f429c47342"/>
        <codeBase version="4.112.3.0" href="FILE://Oracle.DataAccess.dll"/>
        <publisherPolicy apply="no"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <!--Add the above Section to run Oracle 11 and 12 side By Side  -->