Где я могу разместить свой код Ioc (ninject) в моем проекте уровня сервиса? - PullRequest
1 голос
/ 15 января 2011

У меня есть 3 файла проекта

webui - controllers and views
framework - service layer and repos
tests- unit tests

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

Мой репозиторий просто говорит, делает базу данных и возвращает данные.

Теперь, если я хочу выполнить это модульное тестирование, мне нужно иметь поддельные сервисные слои и поддельные репозитории.

таким образом я могу тестировать контроллеры изолированно и сервисные уровни изолированно.

Так, где я могу поместить мой недействительный код в библиотеку классов фреймворка, чтобы я мог использовать его со своим сервисным уровнем?

Редактировать

Стивен, вы говорите, что я должен делать что-то подобное

// установка ninject в глобальном aspx с расширением mvc

// теперь связываем вещи

private class SportsStoreServices : NinjectModule
        {
            public override void Load()
            {

                Bind<IAdminService>().To<AdminService>();
                Bind<IAdminRepo>().To<AdminRepo>();
            }
        }

// контроллер

public class AccountController : Controller
    {
        //
        // GET: /Account/

   private IAdminService adminService;

 public AccountController(IAdminService adminService)
        {
   this.adminService = adminService;
 }


        public ActionResult Login()
        {
            var getAllAdmins = adminService.GetAllAdmins();
            return View();
        }

    }

// Сервисный уровень

public class AdminService : IAdminService
{

   private IAdminRepo adminRepo;
   public AdminService(IAdminRepo adminRepo)
   {
      this.adminRepo = adminRepo;
   }

   public List<Admins> GetAllAdmins()
   {

       return adminRepo.GetAllAdmins();
   }   

}


//Repo
    public class AdminRepo : IAdminRepo
    {
       public List<Admins> GetAllAdmins()
       {
          // some query to get all admins
       }
    } 

Ответы [ 2 ]

5 голосов
/ 16 января 2011

При правильном (и полном) соблюдении шаблона внедрения зависимостей единственное место, где вам нужно ссылаться на свой контейнер IoC, - это корневой каталог приложения (в вашем случае - веб-проект). Для MVC у вас обычно есть ControllerFactory, который знает, как создавать новые контроллеры, используя вашу конкретную среду IoC. Ваши контроллеры будут спроектированы на основе внедрения конструктора, поэтому ваша платформа IoC может автоматически внедрить все зависимости. Обычно вы будете использовать инжектор конструктора на протяжении всего проекта. Это позволяет позволить остальной части кода оставаться в неведении относительно выбранной реализации IoC.

Для модульных тестов вы обычно используете инжектор конструктора, чтобы вручную вводить зависимости. Это избавляет вас от необходимости настраивать инфраструктуру IoC для ваших модульных тестов. Использование библиотеки IoC в вашем тестовом проекте является болезненным, потому что вы часто хотите, чтобы в каждом тестовом примере возвращались разные зависимости, а тестовые среды часто запускают ваши тесты параллельно. Поэтому лучше всего не использовать в своих тестах какую-либо инфраструктуру IoC, а вызывать конструктор тестируемого типа самостоятельно.

Хитрость для юнит-тестов с DI состоит в том, чтобы поддерживать ваши юнит-тесты в обслуживании. Это можно сделать, например, извлекая создание тестируемого типа в метод фабрики. Это позволяет вам вызывать такой конструктор только в одном месте вашего кода. Когда конструктор изменится, вам придется изменить свой тестовый код в одном месте. Я много узнал о написании поддерживаемых модульных тестов по книге Искусство модульного тестирования . Я могу рекомендовать это.

1 голос
/ 03 февраля 2011

В проекте DI должен находиться в том месте, где может произойти композиция объектов. Например, в проекте Project службы WCF мы можем сделать это с помощью IInstanceProvider, IN asp.net Global.asax. Основное правило: убедитесь, что DI является точкой запуска приложения

...