NHibernate / Castle.ActiveRecord; Сессия-управление; WinForms - PullRequest
4 голосов
/ 05 января 2012

мой первый настоящий (не тестовый) проект NHibernate / Castle.ActiveRecord развивается быстро.Я работаю с NHibernate / Castle.ActiveRecord около месяца, но до сих пор не знаю, как обрабатывать сеансы в моем приложении WindowsForms.

Общий шов методов обработки, который мне не подходит:

  • SessionPerRequest, SessionPerConversation и т. Д. Все работают только для веб-приложений и т. Д.
  • SessionPerApplication не рекомендуется / очень опасен, если я прав.
  • SessionPerThread не очень полезен, посколькуУ меня либо только один поток, поток WindowsForms, либо для каждого нажатия кнопки новый поток.Первое, что заставило бы мое приложение использовать слишком много памяти и хранить старые объекты в памяти.С рабочими потоками для нажатия кнопки ech я бы отключил отложенную загрузку, поскольку мои загруженные объекты будут жить дольше, чем поток.
  • SessionPerPresenter также не работает, потому что обычно я открываю подпрограмму-presenter "в форме, позволяющей пользователю искать / загружать / выбирать некоторые ссылочные объекты (ключ foreigen) и причины, по которым презентатор уничтожен - что означает закрытие сессии - но объект, используемый в" суперпрезентере "для заполнения ссылоксвойство (foreigen key).

Я часами пользовался Google и Bing и много читал, но нашел только один хороший сайт о моем деле: http://msdn.microsoft.com/en-us/magazine/ee819139.aspx.Там SessionPerPresenter используется, но для «подчиненного» ему дается только идентификатор, а не весь объект!И это говорит о том, что в этом примере нет внешних ключей и сценариев, в которых объект возвращается «супер-презентатору».

Вопросов

  1. Есть ли какой-либо другой метод обработки сеанса для windowsforms / desktop-application?
  2. Я мог бы добавить свойство сеанса или параметр session-constructor для всех моих докладчиков, но он не вправеобработка сеанса по всему моему UI-коду.
  3. Когда возникает исключение, NHibernate хочет, чтобы я убил сеанс.Но если это «только» исключение бизнес-логики, а не исключение NHibernate?

Пример

Я пытаюсь привести пример обложекбольшая часть моей проблемы.

// The persisten classes
public class Box
{
  public virtual int BoxId{get;set;}
  public virtual Product Content{get;set;}
  ...
}

public class User
{
  public virtual int UserId{get;set;}
  public virtual IList<Product> AssigenedProducts{get;set;}
  ...
}

public clas Product
{
  public virtual int ProductId{get;set;}
  public virtual string PrductCode{get;set;}
}

.

// The presenter-classes
public class ProductSearchPresenter : SearchPresenter<Product> { ... }
public class ProductEditPresenter : EditPresenter<Product> { ... }
public class UserSearchPresenter : SearchPresenter<User> { ... }
public class UserEditPresenter : EditPresenter<User> { ... }
public class BoxSearchPresenter : SearchPresenter<Box> { ... }
public class BoxEditPresenter : EditPresenter<Box> { ... }
// The search-presenters allow the user to perform as search with criterias on the class defined as generic argument and to select one of the results
// The edit-presenters allow to edit a new or loaded (and given as parameter) object of the class defined as generic argument

Теперь у меня есть следующие варианты использования, которые все могут быть выполнены в одном приложении одновременно и асинхронно (использованиепросто переключается между докладчиками).

  1. с использованием экземпляра BoxSearchPresenter для поиска и выбора объекта
    1. часть этого варианта использования заключается в использовании экземпляра ProductSearchPresenter для заполнения критерияBoxSearchPresenter
    2. часть этого варианта использования заключается в использовании экземпляра BoxEditPresenter для редактирования и сохранения выбранного объекта экземпляра BoxSearchPresenter
  2. с использованием экземпляра UserSearchPresenter впоиск и выбор объекта
    1. . Частью этого варианта использования является использование экземпляра UserEditPresenter для редактирования и сохранения сплющенного объекта UserSearchP.resenter
    2. часть этого варианта использования заключается в использовании ProductSearchPresenter для поиска и выбора объектов, которые будут добавлены в User.AssignedProducts.
  3. Использование экземпляра ProductSearchPresenter для поиска ивыберите объект.
    1. часть этого сценария использования - использование экземпляра ProductEditPresenter для редактирования и сохранения выбранного объекта ProductSearchPresenter.

Это лишь небольшая коллекция вариантов использования, но у меня уже есть много проблем.

  • UseCase 1. и 2. работают одновременно в одном и том же потоке пользовательского интерфейса.
  • UseCase 1.1.и 2.2.вернуть выбранные объекты другим докладчикам, которые используют эти объекты дольше, чем существуют докладчики, которые загрузили объект.
  • UseCase 3.1. может изменить объект, загруженный из 2.2./1.1. до 3.1. был запущен, но когда 2.2./1.1. совершено до 3.1. будет завершен, объект будет сохранен, и будет невозможно выполнить «откат» 3.1.

1 Ответ

2 голосов
/ 13 января 2012

Вот лишь краткий обзор того, что я нашел наилучшим образом вписать в нашу архитектуру приложений WinForms (на основе MVP).

Каждый докладчик зависит от конструктора, который ему нужен, например, если у вас есть InvoicePresenterтогда у вас будет InvoiceRepository в качестве зависимости, но, вероятно, у вас будет CustomerRepository и многие другие в зависимости от сложности (CustomerRepsitory для загрузки всех клиентов в поле со списком клиентов, если вы хотите изменить клиента в счете, и все в таком духе).Затем каждый репозиторий имеет аргумент-конструктор для UnitOfWork.Либо вы можете абстрагировать сеанс с помощью шаблона UnitOfWork, либо вы можете сделать так, чтобы ваши репортеры зависели от ISession.

Все связано между собой контейнером IoC, где мы создаем презентаторов на основе «контекста».Это очень простая концепция, контекст для каждого докладчика и для всех подчиненных, который, в свою очередь, мы создаем как составной блок более сложных докладчиков, чтобы уменьшить сложность (если, например, у вас есть несколько вкладок с опциями для редактирования какого-либо объекта или чего-то еще).

Таким образом, на практике этот контекст основан на 90% временной формы, потому что одна форма - это как минимум один докладчик / представление.

Итак, чтобы ответить на ваши вопросы:

  1. Сеанс для докладчика и сеанс для разговора (также работает с WinForms) - это только реально используемые шаблоны (и открывающие закрытые сеансы везде, но не очень хороший способ справиться с этим) -

  2. это лучше всего решить, если репозитории зависят от сессии, а не от докладчиков.Вы делаете докладчиков зависимыми от репозиториев, репозитории зависят от сеанса, а когда вы создаете все, вы даете им общий сеанс;но, как я еще раз заявляю, это практично только тогда, когда это делается в контексте.Вы не можете поделиться сеансом для счетов, редактирующих докладчика, и других клиентов, редактирующих докладчика;но вы можете поделиться сеансом при редактировании счета через основного докладчика, а также сведения о счете и примечаниях к счету-суб-докладчику.

  3. Уточните, не понял этого ...

...