Ninject - 使用运行时值设置依赖项构造函数

时间:2013-08-16 17:58:04

标签: dependency-injection ninject

我是DI / Ninject的新手,我似乎无法弄明白我需要做什么。我有这样的服务:

public class ArchiveService : IArchiveService
{
    private string sAuditUser = "USER";

    public ArchiveService(string AuditUser)
    {
        sAuditUser = AuditUser;
    }
    ...
}

我目前正在实例化这样的服务:

string sUser = HttpContext.Session["UID"].ToString();
ArchiveService svcArchive = new ArchiveService(Session["UID"].ToString());

当用户成功登录帐户页面时,将设置会话值。如何设置服务依赖项以便正确获取该值?

1 个答案:

答案 0 :(得分:1)

通常,您应该尝试阻止尝试将原始值注入服务,除非:

  • 它们是配置值, - 和 -
  • 他们只需要注入一个服务。

如果其中任何一个都是假的,则不应直接注入基元。

在您的情况下,您处理上下文信息并且值得拥有自己的抽象:

public interface IUserContext
{
    string Name { get; }
}

有了这个抽象,所有需要了解当前用户的操作的服务正在执行的所有服务都可以依赖于这种抽象。

public class ArchiveService : IArchiveService
{
    private IUserContext userContext;

    public ArchiveService(IUserContext userContext)
    {
        this.userContext = userContext;
    }
}

您现在唯一要做的就是创建一个您注册的IUserContext实现。这种实现看起来完全取决于您运行的应用程序类型(ASP.NET,Win Forms,WCF等),但在您的特定情况下,这是如何实现的:

public class AspNetUserContext : IUserContext
{
    public string Name
    { 
       get
       {
           return HttpContext.Current.Session["UID"].ToString();
       }
    }
}

这就是你注册的方式:

Bind<IUserContext>().To<AspNetUserContext>().InSingletonScope();

为单个字符串创建接口似乎很愚蠢,但它有一些明显的优势:

  • 新的抽象传达了更清楚的价值。 string可以是任何东西。它可以是路径,连接字符串等。
  • 抽象集中了如何将这些用户信息传递到一个地方的知识。
  • 由于新的抽象是明确的,因此在容器中注册它变得容易得多。配置将更加可维护。
  • 解决方案更不容易出错,因为我们集中了用户信息的提供方式。