【问题标题】:Injecting runtime value into Unity dependency resolver将运行时值注入 Unity 依赖解析器
【发布时间】:2014-04-29 20:22:44
【问题描述】:

我正在开发一个 webapi 项目并使用 Unity 作为我们的 IOC 容器。我有一组分层依赖项,如下所示:

unityContainer.RegisterType<BaseProvider, CaseProvider>(new HierarchicalLifetimeManager());
unityContainer.RegisterType<IRulesEngine, RulesEngine>();
unityContainer.RegisterType<IQuestionController, QuestionController>();
unityContainer.RegisterType<IAPIThing, WebAPIThing>();

现在 BaseProvider 的构造函数接受一个 int 作为参数,它是 Case 标识符。 WebAPIThing 在其构造函数中采用 BaseProvider。通常在非 Web 场景中,我会使用以下内容注入案例 ID:

public static IAPIThing GetIAPIThing(int caseId)
{
  return CreateUnityContainer().Resolve<IAPIThing >(new ParameterOverride("caseId", caseId).OnType<CaseProvider>());
}

但这仅在我明确调用该方法时才有效。在 Web API 场景中,我使用的是 config.DependencyResolver = new UnityDependencyResolver(unityContainer); 解析我的 api 控制器。

我想我仍然需要影响 DependencyResolver 在运行时解析 BaseProvider 对象的方式。

有人必须做类似的事情吗?

编辑 1
我尝试使用以下似乎可行的方法:

unityContainer.RegisterType<BaseProvider>(
        new HierarchicalLifetimeManager()
        , new InjectionFactory(x => 
                    new CaseProvider(SessionManager.GetCaseID())));

【问题讨论】:

  • caseId 来自哪里? caseId 的调用者是如何构造GetIAPIThing 的?这个值是否来自会话、请求参数、cookie?
  • @Steven CaseId 将从会话中存储和提供。

标签: c# asp.net-web-api dependency-injection unity-container


【解决方案1】:

您正在尝试将运行时值(案例 ID)注入对象图中,这意味着您使对象图的配置、构建和验证变得复杂。

您应该做的是将该原始值提升为它自己的抽象。起初这听起来很傻,但这样的抽象在描述其功能方面会做得更好。例如,在您的情况下,抽象可能应该命名为ICaseContext

public interface ICaseContext
{
    int CurrentCaseId { get; }
}

通过将int 隐藏在这个抽象后面,我们有效地:

  • 使int 的角色非常明确。
  • 删除了与您的应用程序可能需要的 int 类型的任何其他值的任何冗余。
  • 将此int 的解析延迟到构建对象图之后。

您可以在应用程序的核心层中定义这个ICaseContext,每个人都可以依赖它。在您的 Web API 项目中,您可以定义此 ICaseContext 抽象的特定于 Web API 的实现。例如:

public class WebApiCaseContext : ICaseContext
{
    public int CurrentCaseId
    {
        get { return (int)HttpContext.Current.Session["CaseId"];
    }
}

这个实现可以注册如下:

unityContainer.RegisterType<ICaseContext, WebApiCaseContext>();

更新

请注意,您自己的new CaseProvider(SessionManager.GetCaseID()) 配置并不能解决所有问题,因为这意味着在验证对象图时必须有可用的会话,而在应用程序启动期间和单元/集成测试中都不是这种情况.

【讨论】:

  • 谢谢,重构案例 ID 并将其放在上下文中是一个很好的解决方案。
猜你喜欢
  • 1970-01-01
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
相关资源
最近更新 更多