2016-01-30 2 views
2

Итак, пытаясь провести тестирование наших контроллеров, я пытаюсь уменьшить наши контроллеры и сделать их более проверяемыми. Мы используем шаблон 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 за один раз в конструкторе, чтобы все методы контроллера могли использовать экземпляр?

+0

Возможным решением является использование контейнера для инъекций зависимостей, строка 'AutoFac' и объявление ваших зависимостей в качестве интерфейсов, таких как' IAccountServices'. после этого вы можете зарегистрировать это как единый экземпляр. 'builder.Register (). (). SingleInstance();' – tchelidze

+0

Использование контейнера DI, поддерживающего создание экземпляра запроса (вероятно, все широко используемые контейнеры имеют такую ​​поддержку), вероятно, лучшее решение ... (на самом деле не отвечайте на свой вопрос). –

+0

MVC не знает, что он должен вызывать ваш контроллер с IPrincipal. Вы должны получить принципала из контекста вашего контроллера в конструкторе. Но посмотрите на использование контейнера DI, это упростит вашу жизнь. –

ответ

4

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

+0

Спасибо за ссылку. Я думаю, что моим самым большим препятствием будет тот факт, что AccountServices требует IPrincipal Controller.User – navig8tr

+0

Не уверен в вашей конкретной ситуации, но вы можете получить идентификатор пользователя из HttpContext.Current.Request.LogonUserIdentity, если используете интегрированную защиту Windows или HttpContext.Current .User.Identity, если используется проверка подлинности форм. –

+0

Извините за мое невежество, но я считаю, что мы используем аутентификацию по формам. Могу ли я получить идентификатор пользователя при вызове конструктора? – navig8tr

Смежные вопросы