【问题标题】:Ninject constructor argumentNinject 构造函数参数
【发布时间】:2011-06-12 16:11:40
【问题描述】:

我有这个界面:

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 容器中,以便在 Ninject 初始化此服务的实例时传入 userName 参数。

有什么想法可以实现吗?

【问题讨论】:

  • 我基本同意 Mike 的描述。有关更多详细信息和解释,我建议您在此处阅读 Ruben Bartelink 的答案:stackoverflow.com/questions/2227548/…。对于您想要实现的目标,这是一个非常彻底的答案。
  • 有人能解释为什么他们对这个问题投了反对票吗?

标签: dependency-injection ninject


【解决方案1】:

技术上的 ninject 答案是像这样使用构造函数参数:

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

当然,您需要弄清楚“karl”的来源。这真的取决于你的应用程序。也许它是一个网络应用程序,它在 HttpContex 上?我不知道。如果它变得相当复杂,那么您可能想要编写 IProvider 而不是进行常规绑定。

【讨论】:

    【解决方案2】:

    另一种方法是注入工厂并使用 Create(string userName) 创建您的依赖项。

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

    似乎不得不创建另一个类,但好处主要来自UserProfileService 接受额外的依赖项。

    【讨论】:

    • ProfilesController 构造函数是否会采用 UserProfileServiceFactory 和 userName?
    【解决方案3】:

    诀窍是在该类中注入用户名。您将此类称为服务,因此它可能会透明地与多个用户一起使用。我看到了两种解决方案:

    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; }
          }
      }
      

    如果可以,请选择选项一。

    【讨论】:

    • 关于选项一,假设 IPrincipal 的具体构造函数采用 userName 参数,该选项有何帮助?
    猜你喜欢
    • 1970-01-01
    • 2023-03-24
    • 2018-03-27
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 2014-03-09
    相关资源
    最近更新 更多