Аргумент Ninject конструктор - PullRequest
4 голосов
/ 12 июня 2011

У меня есть этот интерфейс:

public interface IUserProfileService
{
    // stuff
}

Реализовано:

public class UserProfileService : IUserProfileService
{
    private readonly string m_userName;

    public UserProfileService(string userName)
    {
        m_userName = userName;
    }
}

Мне нужно это ввести в контроллер, как это:

public class ProfilesController : BaseController
{
    private readonly IUserProfileService m_profileService;

    public ProfilesController(IUserProfileService profileService)
    {
        m_profileService = profileService;
    }
}

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

Есть идеи, как мне этого добиться?

Ответы [ 3 ]

5 голосов
/ 14 июня 2011

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

Bind<IUserProfileService>().To<UserProfileService>().WithConstructorArgument("userName", "karl");

Конечно, вам нужно выяснить, откуда взялся "Карл". Это действительно зависит от вашего приложения. Может быть, это веб-приложение и оно находится на HttpContex? Я не знаю. Если это становится довольно сложным, вы можете написать IProvider, а не делать обычную привязку.

3 голосов
/ 13 июня 2011

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

  1. Вставить абстракцию в сервис, который представляет текущего пользователя:

    public class UserProfileService : IUserProfileService
    {
        private readonly IPrincipal currentUser;
    
        public UserProfileService(IPrincipal currentUser)
        {
            this.currentUser = currentUser;
        }
    
        void IUserProfileService.SomeOperation()
        {
            var user = this.currentUser;
    
            // Do some nice stuff with user
        }
    }
    
  2. Создайте реализацию, специфичную для технологии, с которой вы работаете, например:

    public class AspNetUserProfileService : IUserProfileService
    {
        public AspNetUserProfileService()
        {
        }
    
        void IUserProfileService.SomeOperation()
        {
            var user = this.CurrentUser;
    
            // Do some nice stuff with user
        }
    
        private IPrincipal CurrentUser
        {
            get { return HttpContext.Current.User; }
        }
    }
    

Если можете, перейдите к первому варианту.

3 голосов
/ 12 июня 2011

Одна альтернатива - внедрить фабрику и создать свою зависимость, используя Create(string userName).

public class UserProfileServiceFactory
{
    public IUserProfileService Create(string userName)
    {
        return new UserProfileService(userName);
    }
}

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

...