Итак, пытаясь провести тестирование наших контроллеров, я пытаюсь уменьшить наши контроллеры и сделать их более проверяемыми. Мы используем шаблон Service/Reposistory, и у нас есть несколько экземпляров нашего уровня обслуживания. Каждый метод в контроллере создает новый экземпляр служебного уровня. Чтобы исправить это, я хотел бы создать экземпляр одного экземпляра в конструкторе контроллера.Как передать значение конструктору контроллера?
Ниже приведен пример нашего типичного метода контроллера:
public class GroupController : ControllerBase // ControllerBase is derived from System.Web.Mvc.Controller
{
public ActionResult EditGroup(int groupId)
{
EditGroupViewModel model = new EditGroupViewModel();
using (var service = new AccountServices(this.User)) // this.User is an instance of IPrincipal Controller.User {
Group group = service.GetGroupWithRoles(groupId);
// some code to map Group to EditGroupViewModel
}
return View(model);
}
}
Любой метод, который использует AccountServices должен создавать новый экземпляр класса, как показано выше. В идеальном случае AccountServices будет создаваться единовременно в конструкторе контроллера. Однако я не уверен, как это сделать.
Вот что я пробовал:
private readonly AccountServices _service;
public GroupController(IPrincipal user)
{
_service = new AccountServices(user);
}
Однако при размещении точки останова на конструкторе я вижу, что пользователь IPrinicipal остается null.I думает, мое самое большое препятствие является тем фактом, что AccountServices требует IPrincipal Controller.User для создания экземпляра. Как я могу создать экземпляр AccounServices за один раз в конструкторе, чтобы все методы контроллера могли использовать экземпляр?
Возможным решением является использование контейнера для инъекций зависимостей, строка 'AutoFac' и объявление ваших зависимостей в качестве интерфейсов, таких как' IAccountServices'. после этого вы можете зарегистрировать это как единый экземпляр. 'builder.Register(). (). SingleInstance();' –
tchelidze
Использование контейнера DI, поддерживающего создание экземпляра запроса (вероятно, все широко используемые контейнеры имеют такую поддержку), вероятно, лучшее решение ... (на самом деле не отвечайте на свой вопрос). –
MVC не знает, что он должен вызывать ваш контроллер с IPrincipal. Вы должны получить принципала из контекста вашего контроллера в конструкторе. Но посмотрите на использование контейнера DI, это упростит вашу жизнь. –