Domanda

Background:

I have a .NET 4.5 application that uses Enterprise Library 6.0 to connect to an Oracle Database. In order to use the Oracle Data Provider for .NET, you have use EntLibContrib.Data.OdpNet.

I have a separate project and solution that contains the business and data access logic to connect to the database and returns domain objects.

Issue:

I went to use the assemblies in another project (in another solution) and ran into issues. I had added references to the following:

  • The .NET dlls produced by building the other solution
  • Microsoft.Practices.EnterpriseLibrary.Common
  • Microsoft.Practices.EnterpriseLibrary.Data
  • EntLibContrib.Data.OdpNet

After adding the appropriate settings to the configuration it should have worked as it has in other projects -- but when I tried to connect to the database, I received the following error:

The type 'EntLibContrib.Data.OdpNet.OracleDatabase, EntLibContrib.Data.OdpNet' cannot be resolved. Please verify the spelling is correct or that the full type name is provided.

I created a question for this error a while back. I never got a response, but the issue seem to "fix itself" when I added additional config information, but I never dug into what was causing the issue.

Since I ran into this issue again, I investigated and narrowed it that I need to have reference to an object that was part of EntLibContrib.Data.OdpNet. It also works if I have a reference an object that references references an object that is part of EntLibContrib.Data.OdpNet.

My solution was simply to do write a dummy variable in a class of my new project:

private static EntLibContrib.Data.OdpNet.OracleDataReaderWrapper dummyVarNotUsed; 

Even though dummyVarNotUsed is never used, simply having that line allows the EntLibContrib.Data.OdpNet assembly to be referenced correctly.

This is a hack, could someone shed some light on what is happening and how to better reference the dll?

È stato utile?

Soluzione

Based off of this question, and the associated answer, I'd suggest trying to handle the AssemblyResolve event, so something like this:

//in your startup method
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);

//...
private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
    //not sure if this will be what the name is, you'd have to play with it
    if (args.Name == "EntLibContrib.Data.OdpNet.OracleDatabase")
    {
        return typeof(EntLibContrib.Data.OdpNet.OracleDataReaderWrapper).Assembly;
    }
    //not sure if this is best practice or not (to return null if truly unknown)
    return null;
}

That answer does suggest your current solution as the preferred method, but I agree that it does feel hacky. Not sure if this other method will feel any less hacky to you; it does to me in that at least this way you can clearly document this event handler instead of having a bogus variable somewhere with comments like //DON'T REMOVE, VERY IMPORTANT!!!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top