【问题标题】:Fluent NHibernate Solution Structure - How to reference DLL's once in back end of Web App / Console AppFluent NHibernate 解决方案结构 - 如何在 Web 应用程序/控制台应用程序的后端引用 DLL 一次
【发布时间】:2010-02-20 18:28:41
【问题描述】:

我正在使用 Fluent NHibernate 组织 VisualStudio 2008 解决方案,我希望将所有 NHibernate dll 依赖项隐藏在“后端”类库中,并让前端 Web 应用程序或控制台应用程序不了解 NHibernate。

我的解决方案结构如下:

BackEnd -- 类库 -- 业务逻辑和Data Repositories & public API..这个级别私下使用NHibernate进行数据存储,不向前端公开任何NHibernate类

Public -- 类库 --- 前端和后端都使用的没有依赖关系的 POCO 对象。后端使用 NHibernate 来持久化这些对象。

前端 -- 控制台应用程序和一个 MVC Web 应用程序 --(两个前端应用程序 (1) MVC2 Web 应用程序 && (2) 一个控制台应用程序)引用公共和后端项目和只需使用一些公共方法即可使用公共对象与后端进行交互。

我想做的只是在后端引用 NHibernate 及其许多依赖项,让前端应用程序只引用后端项目。但是,如果除了在后端引用它们之外,我没有在前端应用程序中引用 Nhibernate 的每一个依赖项,Fluent BackEnd 在运行时就会崩溃。这是当前端省略引用时它在抱怨找不到 nhibernate dll 时崩溃的后端代码:

   public static ISessionFactory CreateSessionFactory()
    {
        return Fluently.Configure()
         .Database(SQLiteConfiguration.Standard.UsingFile(DbFile))
         .Mappings(m => m.AutoMappings
               .Add(AutoMap.AssemblyOf<EngineInfo>(type => type.Namespace.Contains("BackEnd"))
               .Conventions.Add(DefaultCascade.All())
               .Conventions.Add(DefaultLazy.Never())
               )
             ) //emd mappings
       .ExposeConfiguration(BuildSchema)//Delete and remake a fresh tmp db 
       .BuildSessionFactory();//finalizes the whole thing to send back. 


    }

可能是我不小心将 NHibernate 相关资源暴露给前端应用程序,但我没有收到任何编译时错误,我希望得到一点指导。

如果我确实引用了 Nhibernate 的 dll,一切都运行良好,但在我的前端应用程序中,我在编译时收到以下警告:

*

发现不同的冲突 相同依赖的版本 组装。

*

有什么建议吗?

--更新--

我已将必须在前端引用的 dll 缩小到 NHibernate.ByteCode.Castle.dll 和 System.Data.SQLite 我可以跳过所有其他的并且不会出现运行时错误.. 至少还没有。

我仍然不确定为什么需要任何一个,因为前端从不使用任何 NH 或 SQL lite 资源,除非通过不提供任何 Nhibernate 或 SQLite 资源的后端的公共接口。所有接触 NHibernate 或 SQLite 的类都被标记为 Internal,所以我不确定是什么导致了这种依赖。

visual studio 依赖警告提供了一个解决方案,我有点犹豫要不要应用,因为我不知道为什么首先会出现问题:

您想通过将绑定重定向记录添加到 appconfig 文件来解决这些冲突吗? --- MSDN 关于选项 -- http://msdn.microsoft.com/en-us/library/bb383993.aspx

有什么建议吗?

---更新--- 下面的汤姆似乎复制了我的问题,所以这开始听起来像一个 NHibernate dll 错误。我还尝试从 VS 2008 升级到 2010 并重建整个解决方案并在那里复制错误。在我尝试报告之前,有人想看看我们是否遗漏了什么?

【问题讨论】:

    标签: c# visual-studio-2008 nhibernate fluent-nhibernate


    【解决方案1】:

    我正在开发一个具有类似架构的项目,昨天遇到了类似的问题 - 需要在我的项目中包含对 NHibernate 的引用,即使代码中没有对这些程序集的直接引用。

    否则,出现运行时错误,抱怨找不到 NHibernate.ByteCode.Castle。

    问题出在我的构建方式上。 NHibernate 程序集没有正确传播到我的应用程序的运行时目录,因为我使用的是标准 VS2008 文件夹结构(bin\Debug 等)。

    修复的第一部分是创建一个目录,在其中构建和运行所有程序集。您可以通过将解决方案中所有项目的输出路径(在项目的构建选项卡上)设置为指向此目录来完成此操作。

    修复的第二部分是为所有 NHIbernate refs 以及解决方案中的其他程序集设置 Copy Local = True(您不需要为标准程序集 - 系统等设置此设置)。这会导致 VS 在每次构建时将项目使用的所有程序集复制到公共运行时目录。

    然后您应该能够从所有不直接使用它们的项目中消除 NHibernate 引用。

    这对我有用,但我不禁想知道是否有更好的方法来解决这个问题。但现在可以了。

    编辑:

    经过更多测试后,似乎所有 Castle DLL 都存在问题,最明显的是 NHibernate.ByteCode.Castle。

    我的应用程序中的一个项目是一个包含 NHibernate 逻辑的程序集,其中包含对所有 NHibernate DLL 的引用,包括 NHibernate.ByteCode.Castle。

    当我在另一个项目中添加对该程序集的引用并构建它时,所有 NHibernate DLL 都会被复制到另一个项目的输出目录 - Castle DLL 除外!

    Other people have had similar problems我尝试了一些建议的解决方法,但没有成功。

    我强烈怀疑 Castle DLL 没有正确支持 Microsoft 将相关程序集传播到其他项目的约定,但我没有足够的知识来确定。

    【讨论】:

    • 谢谢!这听起来像我需要的。我会在早上试试这个选项。
    • 非常感谢您的帮助。当我开始实施这个选项时,需要手动设置本地副本并创建特殊的输出目录开始让我担心,因为就像你说的那样,我们真的不明白为什么这是必要的。现在我只有一个“problemlibs”文件夹,我可以在其中一次选择所有问题依赖项并点击“添加引用”。我仍然收到有关版本冲突的 vs 警告,但没有运行时错误。在我找出根本原因之前,我有点喜欢用那个警告标志作为提醒。
    • 我也一直在做更多的测试,并且得到了与昨天不同的结果 - 我完全不清楚为什么行为会发生变化!如果您找到“答案”,请在此处发布!
    • 非常感谢您的帮助。我将取消选择此答案,看看是否有人可以给我们更好的解决方案。如果一周左右没有人这样做,我会回来标记这个,因为它是我们所拥有的最接近的东西。
    【解决方案2】:

    一些与 NHibernate 相关的 dll 可能在 web 项目而不是后端项目中被引用。我真的找不到它,删除所有与 NHibernate 相关的 dll,清理您的解决方案并将它们添加到后端项目中。

    【讨论】:

    • 这是我出现这个问题时的第一个想法,所以我删除了所有引用并将它们一个一个添加回来。我会仔细检查我是否正确(有很多与 NHibernate 相关的 dll,所以我可能会错过一个)。
    • 在重新制定解决方案和大量测试后,我确定后端正确引用了所需的 dll,所以我想我可以排除这个答案。
    • Sql lite 未用于任何 NHibernate 相关项目,可用于我所知道的 Web 项目,也许它是其他地方的参考。当您在后端引用 NHibernate.ByteCode.Castle.dll 时,您不必在 Web 项目中引用它。后端可能不需要直接使用 ByteCode.Castle,但城堡代理工厂会间接使用它,除非您在 NHibernate 中使用不同的代理工厂。
    • 我的描述应该更准确。在我的存储库中,我使用 NHibernate 使用 system.data.sqlite 作为连接器来查询 sqllite 数据库。所以从技术上讲,它不是 NHibernate 依赖项,只是 Nhibernate 碰巧使用的资源。即使我不使用延迟加载,NHibernate 是否会继承并覆盖我的 AutoMapped 类的虚拟属性?也许从我的后端存储库返回的 POCO 类真的是我的 POCO 类的 Nhibernate 依赖子项?
    【解决方案3】:

    我解决了这个问题。在我的 DataAccess 项目(NHibernate 和 NHibernate.ByteCode.Castle 引用所在的位置)中,我创建了这个简单的类:

    /// <summary>
    /// This class is only to fix building issue of NHibernate.ByteCode.Castle.dll 
    /// not being copied to bin directory of projects referencing data access 
    /// (either directly or indirectly)
    /// </summary>
    internal abstract class ReferenceHelper : ProxyFactory
    {
    }
    

    我从不使用这个类(显然),但它的存在帮助 NHibernate.ByteCode.Castle.dll(和 Castle.Core.dll)出现在引用项目的 bin/ 目录中。 在解决方案结构中,我有一个单独的目录,其中放置了所有相关的 dll(NHibernate、Castle、Fluent 等),所以这里没有 GAC。

    【讨论】:

    • 感谢您的工作。如果这个问题不存在就好了,但很高兴知道有解决方案。
    【解决方案4】:

    您需要预先加载或 NHibernateUtils。在通过网络发送对象之前初始化您的对象,我怀疑是城堡代理包装器让您感到悲伤。

    【讨论】:

    • 我应该提到我目前正在使用 .Conventions.Add(DefaultCascade.All()) .Conventions.Add(DefaultLazy.Never()) 这不应该解决任何初始化问题吗?此外,如果我有一个惰性加载程序问题,即使使用额外的 dll 引用,我似乎仍然会在前端出现运行时错误,因为此时连接已关闭,但只要我添加神秘的副本,一切都会正常工作dll 引用。
    • 我更新了我的问题的代码部分,以显示我如何关闭延迟加载但仍然遇到同样的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多