MVC3, RavenDB, AutoMapper, IoC / DI и Geese — где я должен использовать связанные с ними репозитории?

#asp.net-mvc-3 #architecture #ravendb

#asp.net-mvc-3 #архитектура #ravendb

Вопрос:

Я очень новичок в RavenDB и MVC3, в частности, в использовании (не концепции) IoC. Итак, просто чтобы предупредить вас, что это будет звучать как вопрос для очень начинающих.

В заключение: у меня есть модель предметной области, допустим, это

 public class Goose
  

Внутри этого класса у меня может быть более сложный объект в качестве свойства

     public Beak beak { get; set; }
  

В RavenDB нам справедливо рекомендуется [JsonIgnore] это свойство или не иметь его вообще и вместо этого иметь ссылочный идентификатор, например

     public String beakId { get; set; }
  

Где-нибудь по пути в моем приложении MVC3 я захочу просмотреть гуся, и, возможно, я захочу отобразить пользователю что-нибудь о Гусе и его клюве (должно ли это быть клювом?). Итак, да, мне нужна модель представления, верно?

 public class GooseModel
{
    public String BeakColour { get; set; }
    public String BeakLength { get; set; }
    ...etc
}
  

Верно, итак, предполагая, что у меня есть какое-то хранилище GooseRepository и какое-то хранилище BeakRepository, вот простой вопрос….

Я нахожусь в классе GooseController и загружаю Goose для просмотра. В какой момент я использую BeakRepository и кто должен знать об этом? GooseController знает о GooseRepository и загружает Goose по идентификатору. На данный момент у нас могло бы быть какое-то свойство внутри класса Goose, которое представляет весь Beak, но я действительно не хочу вводить BeakRepository в GooseRepository, не так ли? Хорошо, возможно, когда я создам GooseModel из найденного мной Goose, я смогу получить свойства GooseModel для BeakColour и BeakLength, каким образом? Ну, мне нравится AutoMapper, поэтому, возможно, моя карта для GooseModel из Goose использует BeakRepository для поиска Beak, а затем извлекает два свойства Beak для заполнения полей GooseModel.. это тоже кажется неправильным… итак, что осталось? GooseController.. должен ли контроллер Goose знать о BeakRespository, а затем находить и устанавливать BeakColour и BeakLength!? это, безусловно, тоже кажется совершенно неправильным..

Итак, где это делается? контроллер, доменный объект, mapper или что-то еще? Возможно, у меня должно быть частичное представление типа Beak, который используется в представлении Goose?..

Комментарии:

1. Я бы на самом деле сказал, что в Raven вы, вероятно, хотите, чтобы Beak был сложным объектом / свойством goose, а не отдельным документом. Как правило, примеры для такого рода вещей очень, очень плохие, когда дело доходит до documentdbs.

Ответ №1:

Я склонен объединять такого рода логику в сервис / бизнес-уровень ( GooseService ), который я затем внедряю в контроллер. ваш уровень обслуживания может принимать GooseRepository и BeakRepository и возвращать разрешенный объект, который сопоставил GooseViewModel вместе.

Комментарии:

1. Ах, значит, GooseService будет нести ответственность за генерацию / отображение GooseModel? Я предполагаю, что здесь будет задействован какой-то распознаватель, который отвечает за предоставление GooseService?

2. правильно. в зависимости от ваших предпочтений, вы просто выбираете контейнер ioc и подключаете его. вам нужно будет создать пользовательский DependencyResolver для выбранного вами контейнера ioc, поскольку именно так будут построены ваши контроллеры. По умолчанию я использую structuremap, но ninject хорош, и я слышал хорошие отзывы о более новых версиях unity.

3. Спасибо! Я изучал их и начал со StructureMap, но я должен сказать, что я изо всех сил пытаюсь найти простой пример IoC с MVC3, который использует StructureMap и четко определяет, куда что поместить. Я могу видеть, как код будет выполняться и запускать UT, но неясно, как подключить его при запуске приложения asax

4. вот начало для завершения structuremap mvc3. это достойная реализация. stevesmithblog.com/blog / …

Ответ №2:

Хм, … читая ваш вопрос, я настоятельно рекомендую вам забыть о сервисном уровне и уровне хранилища. Если у вас нет действительно веских причин для их сохранения (тестирование не является одной из них, поскольку в RavenDB есть EmbeddableDocumentStore, что быстро и просто), извлеките их, чтобы воспользоваться некоторыми очень приятными функциями RavenDB.

На самом деле я написал пост о том, почему, по моему мнению, вам обычно следует избегать этих слоев:http://daniellang.net/keep-your-code-simple/ Речь идет о NHibernate, но концепции применимы и здесь.

Следует ли вам денормализовать свойства BeakColor и BeakLength в вашем документе Goose, зависит от потребностей ваших приложений. Если вас устраивает термин «совокупный корень», то эмпирическое правило заключается в том, что это, как правило, ваши документы. Если вы не уверены, следует ли применять денормализацию, избегайте ее и используйте .Include(goose => goose.Beak) вместо этого при загрузке вашего Goose.

Пожалуйста, дайте мне знать, имеет ли это смысл для вас.

Комментарии:

1. В программировании никогда не бывает истинно «правильного» способа выполнения чего-либо, и я довольно разочарован количеством различных подходов к MVC3. Говоря это, ваше предложение отказаться от уровня репозитория интересно. В настоящее время я пытаюсь изучить наилучшую практику, поэтому «необходимость» на самом деле не является фактором. Я полагаю, я все еще мог бы использовать репозиторий и попросить его включить Beak при извлечении из Raven, а затем заполнить несериализованное свойство объекта из beakId. Я на правильном пути?

2. Ha! Я прочитал вашу статью, очень, очень хороший момент. Моя карьера началась с классического ASP-встроенного SQL с использованием ADO days, и я должен сказать, что я мог бы сделать все очень быстро. Конечно, я вырос из этого и использовал много материалов VB / C COM и позже .Net. Но у меня возникает неприятное чувство каждый раз, когда я начинаю с чего-то недавнего. Есть несколько замечательных идей, но их не обязательно использовать все сразу..

3. Рад слышать, что вам нравится идея. Что касается заполнения объекта Goose, я не уверен, что понимаю ваш вопрос. Это может помочь вам взглянуть на образец RaccoonBlog ( github.com/ayende/RaccoonBlog ). Если нет, вы также можете отправить мне электронное письмо.