Свободная структура решения NHibernate - Как обращаться к DLL один раз в серверной части веб-приложения / консольного приложения - PullRequest
3 голосов
/ 20 февраля 2010

Я организую решение VisualStudio 2008, используя Fluent NHibernate, и я хотел бы сохранить все зависимости dll NHibernate, скрытые в библиотеке классов «Back End», и позволить интерфейсному веб-приложению или консольному приложению не знать о NHibernate.

Моя структура решения выглядит следующим образом:

BackEnd - Библиотека классов - Бизнес-логика и репозитории данных и общедоступный API-интерфейс. Этот уровень использует NHibernate для хранения данных в частном порядке и не предоставляет никакие классы NHibernate для внешнего интерфейса

Public - Библиотека классов --- POCO Объекты без зависимостей, используемые как интерфейсом, так и компонентом. Backend использует NHibernate для сохранения этих объектов.

Front End - Консольное приложение и веб-приложение MVC - (Два интерфейсных приложения (1) Веб-приложение MVC2 && (2) консольное приложение) ссылаются на проекты Public и Back End и просто используйте несколько открытых методов для взаимодействия с Back-end с помощью открытых объектов.

Что я хотел бы сделать, так это только сослаться на NHibernate и его многочисленные зависимости, когда-то в Back End, и чтобы приложения Front End просто ссылались на бэкэнд-проект. Тем не менее, Fluent BackEnd аварийно завершает работу во время выполнения, если я не ссылаюсь на каждую из зависимостей Nhibernate в моем приложении переднего плана в дополнение к ссылкам на них в Back end. Вот код Back End, который вылетает при жалобе, что не может найти библиотеки nhibernate, когда внешний интерфейс пропускает ссылку:

   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 для приложений переднего плана, но я не получаю никаких ошибок во время компиляции, и мне бы хотелось немного поработать.

Если я ссылаюсь на dll Nhibernate, все работает нормально, но в моих приложениях переднего плана я получаю следующее предупреждение во время компиляции:

*

Найдены конфликты между разными версии того же зависимого сборка.

*

Есть предложения?

- Обновление -

Я сузил библиотеки, на которые я должен ссылаться в начале, до NHibernate.ByteCode.Castle.dll и System.Data.SQLite Я могу пропустить все остальные и не получить ошибки во время выполнения .. по крайней мере, пока нет.

Я до сих пор не уверен, зачем это нужно, потому что внешний интерфейс никогда не использует ресурсы NH или SQL lite, кроме как через открытый интерфейс внутреннего интерфейса, который не предлагает никаких ресурсов Nhibernate или SQLite. Все классы, которые касаются NHibernate или SQLite, помечены как внутренние, поэтому я не уверен, что может вызвать эту зависимость.

Визуальное предупреждение о зависимости от студии предлагает решение, которое я не решаюсь применить, так как не знаю, почему проблема возникла в первую очередь:

Хотите исправить эти конфликты, добавив записи перенаправления привязки в файл appconfig? --- MSDN по выбору - http://msdn.microsoft.com/en-us/library/bb383993.aspx

Любой совет?

--- Update --- Том ниже, кажется, повторил мою проблему, так что это начинает звучать как ошибка DLL NHibernate. Я также попытался обновить VS 2008 до 2010, перестроить все решение и повторил ошибку там. Кто-нибудь хочет взглянуть, чтобы убедиться, что мы что-то не упустили, прежде чем я сообщу об этом?

Ответы [ 4 ]

3 голосов
/ 25 февраля 2010

Я работаю над проектом со схожей архитектурой и столкнулся с похожими проблемами только вчера - мне нужно было включить ссылки на NHibernate в мой проект, хотя в коде нет прямых ссылок на эти сборки.

В противном случае получена ошибка времени выполнения с жалобой на невозможность найти NHibernate.ByteCode.Castle.

Проблема оказалась в том, как я строил. Сборки NHibernate не были должным образом перенесены в каталог времени выполнения моего приложения, потому что я использовал стандартную структуру папок VS2008 (bin \ Debug и т. Д.).

Первая часть исправления заключалась в создании единого каталога, в котором все сборки собираются и запускаются. Это можно сделать, задав путь вывода (на вкладке «Сборка») для всех проектов в вашем решении, чтобы он указывал на этот каталог.

Вторая часть исправления состояла в том, чтобы установить Copy Local = True для всех ссылок NHIbernate, а также других сборок в вашем решении (вам не нужно устанавливать это для стандартных сборок - System и т. Д.). Это приводит к тому, что VS копирует все сборки, используемые проектом, в общий каталог времени выполнения при каждом построении.

После этого вы сможете удалить ссылки NHibernate из всех проектов, в которых они не используются напрямую.

Это сработало для меня, но я не могу не задаться вопросом, есть ли лучший способ решить эту проблему. Но пока это подойдет.

Edit:

После еще одного тестирования выясняется, что существует проблема со всеми DLL-библиотеками Castle, в частности NHibernate.ByteCode.Castle.

Одним из проектов в моем приложении является сборка, содержащая логику NHibernate, которая содержит ссылки на все библиотеки DLL NHibernate, включая NHibernate.ByteCode.Castle.

Когда я добавляю ссылку на эту сборку в другой проект и собираю ее, все библиотеки DLL NHibernate копируются в выходной каталог другого проекта - , кроме библиотек Castle! .

У других людей были похожие проблемы Я попробовал некоторые из предложенных обходных путей, но безуспешно.

Я сильно подозреваю, что DLL-библиотеки Castle должным образом не поддерживают соглашения Microsoft о распространении зависимых сборок в другие проекты, но не знают достаточно, чтобы быть уверенными.

2 голосов
/ 12 октября 2011

Я работал над этой проблемой. В моем проекте 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 / проекта. В структуре решения у меня есть отдельный каталог, в который я поместил все связанные библиотеки (NHibernate, Castle, Fluent и т. Д.), Поэтому здесь нет GAC.

2 голосов
/ 20 февраля 2010

Некоторые из связанных с NHibernate dll, вероятно, упоминаются в веб-проекте, а не в бэкэнд-проекте. Если вы действительно не можете найти его, удалите все связанные с NHibernate библиотеки DLL, очистите свое решение и просто добавьте их в бэкэнд-проект.

1 голос
/ 01 марта 2010

Вам нужно активировать загрузку или NHibernateUtil. Инициализировать ваши объекты перед отправкой по проводам, я подозреваю, что это оболочка прокси-замка, которая вызывает у вас горе.

...