2016-06-23 8 views
0

В 5 приложения ASP.NET MVC, учитывая мы имеем interface IUserRepository и конкретную реализацию class UserRepository : IUserRepository, зарегистрированного в качестве такого использования Autofac:Регистрация внутренняя зависимость с помощью Autofac в ASP.NET MVC

builder.RegisterType<UserRepository>() 
     .As<IUserRepository>(); 

и контроллеры, зарегистрированных в качестве например:

using Autofac.Integration.Mvc; 

builder.RegisterControllers(typeof(MvcApplication).Assembly); 

Если бы мы имели контроллер, такие как:

public class JumpController : System.Web.Mvc.Controller 
{ 
    public AppUser CurrentUser 
    { 
     get 
     { 
      // `this.User` is `System.Security.Principal.IIdentity` 
      return AppUser.Find(this.User.Identity.Name); 
     } 
    } 

    public ActionResult Create() 
    { 
     return this.View(); 
    } 

    [HttpPost] 
    public ActionResult Create() 
    { 
     // Sweet! 
     this.CurrentUser.Jump(); 

     return this.RedirectToAction("Create"); 
    } 
} 

Где AppUser является объектом домена, таких как:

public class AppUser 
{ 
    public string UserName { get; private set; } 

    public void Jump() 
    { 
     this.UserRepository.Jump(this); 
    } 

    public static AppUser Find(string userName) 
    { 
     return this.UserRepository.Find(userName); 
    } 

    // we don't want consumers of the `AppUser` type know about our private matters ... 
    private IUserRepository UserRepository 
    { 
     get 
     { 
      // ... and we *wish* `AppUser` didn't "know" about Autofac either! ;-(
      return AutofacDependencyResolver.Current.RequestLifetimeScope.Resolve<IUserRepository>(); 
     } 
    } 
} 

Как мы могли зарегистрировать class UserRepository : IUserRepository в лучшую сторону, так что AppUser «не знает» о AutofacDependencyResolver, возможно без ущерба для желаемого скрытие зависимостей?

+2

Часть выгоды инверсии управления заключается в оказании помощи в тестировании, во многом таким же образом дизайн TDD воздействий и контролируемости. Пытаясь так сильно скрыть «IUserRepository» от всего, включая инъекцию конструктора, вы действительно наступаете на территорию анти-шаблона дизайна. Если это действительно сложно сделать, что вы пытаетесь сделать ... иногда это красный флаг. –

ответ

0

Если вы хотите, чтобы решить определенный вопрос, следует использовать Constructor Dependency Injection.

  1. Контроллер использует инъекцию JumpController(AppUser appUser).
  2. Класс AppUser использует инъекции для хранилища.

Пример: (не были протестированы)

public class JumpController : System.Web.Mvc.Controller 
{ 
    private AppUser _appUser { get; set; } 

    public JumpController(AppUser appUser) 
    { 
     _appUser = appUser; 
    } 

    [HttpPost] 
    public ActionResult Create() 
    { 
     string username = User.Identity.Name; 
     _appUser.Jump(username); 
     return this.RedirectToAction("Create"); 
    } 

    // Rest of the code 
} 

public class AppUser 
{ 
    private IUserRepository _userRepository { get; set; } 

    public AppUser(IUserRepository userRepository) 
    { 
     _userRepository = userRepository; 
    } 

    public void Jump(string username) 
    { 
     _userRepository.Jump(this); 
    } 

    // Rest of the code 
} 
+0

Таким образом, вы открыли «IUserRepository» для публичного интерфейса «AppUser» (именно этого я бы хотел избежать и вместо этого «настроить» через Autofac, а не публиковать его публично). Кроме того, я не буду следовать за вами, когда вы предложили передать 'username' в качестве параметра в' AppUser # Jump'. Почему это? – Ali

+0

Возможно, было бы лучше, если бы фабрика делегатов или вложение свойств было лучше? Не уверен, и мне кажется, что я не могу обойти их. – Ali

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