Каков наилучший способ организации решения ASP.Net MVC с помощью внедрения зависимостей? - PullRequest
14 голосов
/ 08 июня 2009

Я нахожусь на ранней стадии разработки нового проекта ASP.Net MVC и использую этот проект, чтобы попасть в DI. Я почти уверен, что собираюсь использовать Карту структуры, но это не то, о чем я спрашиваю. Я пытаюсь понять, как лучше организовать свое решение. Получают ли и проект модульного теста, и модель файл конфигурации для сопоставления их зависимостей, или существует один класс для управления ими всеми?

Кроме того, есть ли ловушки для новичков, которых следует избегать, прежде чем я зайду слишком далеко в этом?

Большое спасибо, все .....

Обновление Я должен добавить, что когда я говорю «организовать решение», я имею в виду не количество файлов / папок и т. Д., А скорее как структурировать классы, связанные с DI. В частности, как управлять загрузчиком. Я вижу, где плохая формулировка с моей стороны может вызвать путаницу.

Ответы [ 3 ]

11 голосов
/ 08 июня 2009

Если вы единственный, кто работает над проектом, я бы сделал , что имеет смысл для вас сначала . Нет ничего хуже, чем навязать вам директорию или структуру проекта, которые вы считаете неинтуитивными. Класс BaseController находится в папке \ Core \ или в папке \ Controller \? Лично я бы посмотрел в контроллере, но некоторые люди клянутся, что он должен быть в \ Core \ или \ Bases.

Первая ловушка для новичка думает, что вы можете неправильно организовать свой код, и это как-то отражается на успехе проекта. Я видел проекты, в которых 30 файлов находились в одной папке, и другие проекты, в которых было 20 папок для 30 файлов.

Вторая ловушка для новичка забывает, что по сравнению с другими языками у вас есть преимущества удивительного интеллектуального анализа, инструментов навигации по коду и поддержки рефакторинга в Visual Studio. У вас также есть компилятор, который делает размещение файла гораздо менее болезненным. Если вы поместите что-то в «неправильное» место, это нормально, вы всегда можете найти его и перетащить туда, где оно должно быть.

Я буду честен, я сейчас работаю над проектом, и я даже не уверен, где находятся определенные классы в моей файловой структуре. Перейти к определению / объявлению - это сочетания клавиш, которые я часто использую. Потому что только я работаю с кодом, это нормально. Если бы мне пришлось добавить в проект другого разработчика, я бы, наверное, все очистил.

Лично я склонен помещать интерфейсы с их типами реализации в одну и ту же папку. IPaymentGateway находится в той же папке, что и AuthorizeNetGateway и PaypalGateway. Если я не могу просмотреть все файлы в этой папке одновременно на боковой панели обозревателя решений, то я перемещаю все файлы шлюза в папку \ Gateway \.

С добавлением Dependency Injection к смеси я бы посоветовал вам заниматься только взрывами пространства имен. Худшее, что вы можете сделать, - это загромождать ваши загрузчики и файлы длинными, используя объявления и псевдонимы.

ForRequestedType<Customer>

чище, чем

using KevDog.Models
using Customer=KevDog.Models.Customer

или

ForRequestedType<KevDog.Models.Customer>

Другим способом избежать этой проблемы является явное указание при именовании: Customer, CustomerViewModel, CustomerController, CustomerDataRow, CustomerView

Для TDD вам почти нужно иметь два загрузчика для управления вашими конкретными типами. Вы действительно не хотите, чтобы ваши модульные тесты использовали AuthorizeNetGateway: IPaymentGateway, а скорее StubGateway: IPaymentGateway.

Теперь я также новичок в DI, поэтому я стараюсь делать все очень просто и отражать учебники и документацию 101 уровня. Введение в динамическое внедрение, основанное на конфигурации сборки, следует использовать только тогда, когда этого требует конкретная ситуация, и вы точно знаете, почему вы это делаете.

Я обычно сохраняю структуру по умолчанию для приложений MVC. Просто проще иметь свой код в той же структуре, что и 99% всех уроков и видео.

Надеюсь, это поможет.

2 голосов
/ 22 июля 2009

Для поощрения лучшего TDD. Есть два проекта тестирования и / или пространства имен X.Unit.Tests & X.Integrations.Tests.

У меня есть мой DI-код в моем основном проекте в «каталоге пространства имен» (/ Config), но в моих тестах интеграционного кода я мог бы просто вызвать эти реестры или переопределить их, если бы я потребовал в своих базовых приспособлениях или настройках.

например.

/ Config / ServiceRegistry.cs /Config/RepositoryRegistry.cs /Config/Bootstrapper.cs

В global.asax я вызываю Bootstrapper.Init (), и это вызывает x.AddRegistry (new ServiceRegistry ()) и т. Д.

В моих модульных тестах вам не нужно использовать DI только в интеграционных тестах. В моих IntegrationTests, например если я тестирую NHibernate через базу данных, я мог бы инициализировать SM с RepositoryRegistry в TestSetUp с помощью вспомогательного метода, просто упаковывающего GetInstance ().

Я не разделяюсь на проекты .Bootstraper и .Domain, пока мне абсолютно не придется ... Три проекта: X, X.UnitTests, X.Integration, если вам потребуется больше двигаться позже. Я пришел из прошлого / из-за того, что у компании были десятки проектов, которые сначала казались грязными, но не сейчас, я быстро запускаюсь и реорганизую структуру решений позже, если потребуется.

0 голосов
/ 18 июня 2010

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

public VatManager()
 : this(new VatManagerRegistry()) { }

public VatManager(Registry registry)
 : this(new Action<IInitializationExpression>(x => { x.AddRegistry(registry); }))
  {
  }

public VatManager(Action<IInitializationExpression> action)
  {
   ObjectFactory.Initialize(action);
   data = ObjectFactory.GetInstance<IVatManagerData>();
  }

У меня три перегрузки конструктора - конструктор по умолчанию без параметров знает о конкретном реестре StructureMap, который необходимо создать для использования в производственном контексте. Два других позволяют другому коду, который создает экземпляр этого класса менеджера, предоставлять свои собственные Реестр (ы) StructureMap или Действия, чтобы они могли сами управлять инъекциями зависимостей, как, например, в случае автоматического теста, предоставляющего имитации вместо конкретных экземпляров зависимостей. Я должен добавить, что это решение не относится к контексту ASP.NET MVC и не извлекает информацию о конфигурации из файлов * .config.

...