避免创建虚拟变量以强制加载.NET程序集

时间:2014-02-17 17:25:28

标签: c# .net oracle enterprise-library enterprise-library-6

背景

我有一个.NET 4.5应用程序,它使用Enterprise Library 6.0连接到Oracle数据库。要使用Oracle Data Provider for .NET,您必须使用EntLibContrib.Data.OdpNet。

我有一个单独的项目和解决方案,其中包含连接到数据库并返回域对象的业务和数据访问逻辑。

问题:

我去另一个项目(在另一个解决方案中)使用程序集并遇到了问题。我添加了对以下内容的引用:

  • 通过构建其他解决方案生成的.NET dll
  • Microsoft.Practices.EnterpriseLibrary.Common
  • Microsoft.Practices.EnterpriseLibrary.Data
  • EntLibContrib.Data.OdpNet

在配置中添加适当的设置后,它应该像在其他项目中一样工作 - 但是当我尝试连接到数据库时,我收到以下错误:

  

类型' EntLibContrib.Data.OdpNet.OracleDatabase,   EntLibContrib.Data.OdpNet'无法解决。请验证   拼写正确或提供完整的类型名称。

我暂时为此错误创建了question。我从来没有得到过回应,但这个问题似乎已经解决了。#34;当我添加额外的配置信息时,我从来没有挖掘导致问题的原因。

由于我再次遇到这个问题,我调查并缩小了它,我需要引用一个属于EntLibContrib.Data.OdpNet的对象。如果我有一个引用引用引用EntLibContrib.Data.OdpNet一部分的对象的对象,它也可以工作。

我的解决方案只是在我的新项目的类中写一个虚拟变量:

private static EntLibContrib.Data.OdpNet.OracleDataReaderWrapper dummyVarNotUsed; 

即使从未使用过dummyVarNotUsed,只需拥有该行就可以正确引用EntLibContrib.Data.OdpNet程序集。

这是一个黑客,有人可以了解正在发生的事情,以及如何更好地引用该DLL?

1 个答案:

答案 0 :(得分:1)

基于此question以及相关答案,我建议尝试处理AssemblyResolve事件,如下所示:

//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;
}

这个答案确实表明您当前的解决方案是首选方法,但我同意它确实感到hacky。不确定这个其他方法是否会对你不那么惹人厌恶;这对我来说至少在这方面你可以清楚地记录这个事件处理程序,而不是在某处有一个虚假的变量,如//DON'T REMOVE, VERY IMPORTANT!!!

之类的评论