문제

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?

도움이 되었습니까?

해결책

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top