【问题标题】:simple injector - inject into IHttpHandler简单的注入器 - 注入 IHttpHandler
【发布时间】:2018-11-12 12:13:43
【问题描述】:

我正在尝试将 SimpleInjector 嵌入到我的 WCF 项目中(我已按照说明进行操作 here)。到目前为止,除了 IHttpHandler 问题外,一切都很顺利: 当前实现使用 IHttpHandler ,而后者又使用 MyServiceWrapper 静态实例:

public class IsAliveHandler : IHttpHandler
{
    private const string SERVER_ERROR = "Bad";
    private const string SERVER_OK = "OK";

    public void ProcessRequest(HttpContext context)
    {
        var quoteSucceeded = false;
        var isLastLoginSucceeded = MyServiceWrapperContainer.Manager.IsLastLoginSucceeded;
//More logic here ...
    }
}

现在,由于我将我的应用程序移动到使用 SimpleInjector DI 机制,因此我不能使用这种静态访问,因为我想使用与 DI 容器持有的相同的实例。 这里的构造函数注入异常:

[MissingMethodException: Constructor on type '***.Applications.MyServiceWrapperService.KeepAliveHandler.IsAliveHandler' not found.]

有没有办法在这种情况下使用容器?有替代品吗?

一般来说,我可以理解这样的问题是使用状态的味道,但目前这是要求。

【问题讨论】:

    标签: c# wcf dependency-injection simple-injector ihttphandler


    【解决方案1】:

    您的IsAliveHandler 不能有任何构造函数参数(这是您的应用程序框架的约束)。

    相反,您应该将您的IsAliveHandler 设为Humble Object,并将其视为您的Composition Root 的一部分。

    这意味着您从IsAliveHandler 中提取所有有趣的逻辑(例如,提取到IsAliveService)并将IsAliveHandler 更改为如下内容:

    public class IsAliveHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            Bootstrapper.Container.GetInstance<IsAliveService>().Process(context);
        }
    }
    

    换句话说,您让IsAliveHandler 做的唯一事情就是从 DI 容器请求服务并在该已解析服务上调用适当的方法。

    请注意IsAliveHandler 应保持完全无状态:解析IsAliveService 不应存储在任何地方。您应该将其留给 DI 容器来为您提供正确的实例。

    如果此操作在 Simple Injector Scope 的上下文之外运行,您可以将操作包装在这样的 Scope 中:

    public void ProcessRequest(HttpContext context)
    {
        using (AsyncScopedLifestyle.BeginScope(Bootstrapper.Container))
        {
            Bootstrapper.Container.GetInstance<IsAliveService>().Process(context);
        }
    }
    

    【讨论】:

    • 感谢您的精彩见解!关于您在处理程序中建议的服务定位器:目前我使用组合根中的容器为:public class Global : System.Web.HttpApplication { private readonly Container _container = new Container();。正如您在代码中所写:Bootstrapper.Container.GetInstance - 我应该将容器移动到静态 Bootstrapper 类吗?
    • 你可以把Container放在你喜欢的任何地方,只要应用程序的启动路径(可以)得到它。在组合根中使用容器是not 服务定位器反模式。您的处理程序可以被视为组合根的一部分。这就是为什么您应该从处理程序中提取所有(业务)逻辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-21
    • 2015-02-15
    相关资源
    最近更新 更多