如何为特定请求选择一组单独的服务

本文关键字:一组 单独 服务 选择 请求 | 更新日期: 2023-09-27 18:36:35

我正在使用Simple Injector,它似乎做得很好。我真的很想做的一件事,我不知道该怎么做,或者如果可能的话,是根据某个参数更改注册服务列表。

例如:如果我看到一个 URL 参数&debug=true,那么我想清除已注册服务的列表并将它们替换为模拟实现。 这将使我的硒测试变得更加容易。

这可能吗?还是完全疯了?

如何为特定请求选择一组单独的服务

开箱即用,Simple Injector 更喜欢构建预先完全已知的对象图。缺乏允许您根据运行时变量构建不同对象图的内置功能是故意的,因为固定对象图更容易验证,这降低了构建对象图在运行时失败的可能性(在成功调用.Verify()之后)。除了可验证性之外,它还提高了性能。

但是,尽管没有内置任何内容,但仍有许多方法可以根据运行时条件动态切换服务或整个对象图。我想到的三种可能性是使用基于上下文的注入、运行时装饰器和注册一个简单的委托。

下面是委托注册的示例:

container.Register<IMailSender>(() => IsDebug(HttpContext.Current)
    ? container.GetInstance<MailSender>()
    : container.GetInstance<MockSender>());

但即使有可能,您可能还需要考虑不同的方法。例如,使用配置值,而不是使用运行时值。在您的情况下,这似乎非常合理,因为您是否希望能够同时使用生产环境进行 Web 测试?对我来说似乎不太可能。特别是因为在同一台服务器上部署第二个 IIS Web 应用程序非常容易。

因此,您可以为 Selenium 框架创建应用程序的特殊部署,此部署在 web.config 中包含带有 <add key="Debug" value="True" /> 或类似值的值。现在在你的组合根(你引导容器的地方),你可以简单地这样做:

bool debug = bool.Parse(ConfigurationManager.AppSettings["Debug"]);
if (debug) {
    container.Register<IMailSender, MockSender>();
    // more registrations here
} else {
    container.Register<IMailSender, MailSender>();
    // more registrations here
}

这允许在运行时修复对象图,同时仍然能够在部署期间更改内容。