简体   繁体   English

使用Simple Injector使用不同的配置

[英]Use different configurations with Simple Injector

I'm using the Simple Injector Dependency Injection framework and it looks cool and nice. 我正在使用Simple Injector依赖注入框架,它看起来很酷很好。 But after building a configuration and use it, now I want to know how to change from one configuration to another. 但在构建配置并使用它之后,现在我想知道如何从一种配置更改为另一种配置。

Scenario : Let's imagine I've set up a configuration in the Global Asax and I have the public and global Container instance there. 场景 :假设我在Global Asax中设置了一个配置,那里有公共和全局Container实例。 Now I want to make some tests and I want them to use mock classes so I want to change the configuration. 现在我想做一些测试,我希望他们使用模拟类,所以我想改变配置。

I can, of course, build another configuration and assign it to the global Container created by default, so that every time I run a test the alternative configuration will be set. 当然,我可以构建另一个配置并将其分配给默认创建的全局Container ,这样每次运行测试时都会设置备用配置。 But on doing that and though I'm in development context the Container is changed for everyone, even for normal requests. 但是在这样做的时候,虽然我在开发环境中,但Container会针对每个人进行更改,即使是正常的请求也是如此。 I know I'm testing in this context and that shouldn't matter, but I have the feeling that this is not the way for doing this... and I wonder how to change from one configuration to another in the correct way. 我知道我正在测试这个环境,这应该不重要,但我觉得这不是这样做的方式......我想知道如何以正确的方式从一种配置转换到另一种配置。

When doing unit tests, you shouldn't use the container at all. 进行单元测试时,根本不应使用容器。 Just create the class under test by calling its constructor and supplying it with the proper mock objects. 只需通过调用其构造函数并为其提供适当的模拟对象来创建被测试的类。

One pattern that helped me out here a lot in the past is the use of a simple test class-specific factory method. 在过去帮助我很多的一种模式是使用一个简单的测试类特定的工厂方法。 This method centralizes the creation of the class under test and minimizes the amount of changes that need to be made when the dependencies of the class under test change. 此方法集中创建要测试的类,并最小化在测试类的依赖项发生更改时需要进行的更改量。 This is how such factory method could look like: 这就是这种工厂方法的样子:

private ClassUnderTest CreateValidClassUnderTest(params object[] dependencies)
{
    return new ClassUnderTest(
        dependencies.OfType<ILogger>().SingleOrDefault() ?? new FakeLogger(),
        dependencies.OfType<IMailSender>().SingleOrDefault() ?? new FakeMailer(),
        dependencies.OfType<IEventPublisher>().SingleOrDefault() ?? new FakePublisher());
}

For integration tests it's much more common to use the container, and swap a few dependencies of the container. 对于集成测试,使用容器更常见,并交换容器的一些依赖项。 Still, those integration tests will not use the container that you created in your application_start, but each integration test will in that case most likely have its own new container instance, since each test should run in isolation. 尽管如此,这些集成测试不会使用您在application_start中创建的容器,但在这种情况下,每个集成测试很可能都有自己的新容器实例,因为每个测试都应该独立运行。 And even if you did use a single container from application_start, your integration tests are ran from a separate project and won't interfere with your running application. 即使您确实使用了application_start中的单个容器,您的集成测试也是从单独的项目运行的,不会干扰正在运行的应用程序。

Although each integration test should get its own container instance (if any) you still want to reuse as much of the container configuration code as possible. 虽然每个集成测试都应该获得自己的容器实例(如果有的话),但您仍然希望尽可能多地重用容器配置代码。 This can be done by extracting this code to a method that either returns a new configured container instance when called, or configure a supplied container instance (and return nothing). 这可以通过将此代码提取到一个方法来完成,该方法在调用时返回新配置的容器实例,或者配置提供的容器实例(并且不返回任何内容)。 This method should typically do an incomplete configuration and the caller (either your tests or global asax) should add the missing configurations. 此方法通常应执行不完整的配置,调用方(测试或全局asax)应添加缺少的配置。

Extracting this code: allows you to have multiple end application that partly share the same configuration; 提取此代码:允许您拥有部分共享相同配置的多个终端应用程序; allows you to verify the container in an integration test; 允许您在集成测试中验证容器; and allows you to add services that need to be mocked by your integration tests. 并允许您添加需要由集成测试模拟的服务。

To make life easier, Simple Injector allows you to replace existing registrations with new one (for instance a mocked one). 为了简化生活,Simple Injector允许您用新的注册替换现有注册(例如模拟注册)。 You can enable this as follows: 您可以按如下方式启用此功能:

container.Options.AllowOverridingRegistrations = true;

But be careful with this! 但要小心这个! This option can hide the fact that you accidentally override a registration. 此选项可以隐藏您不小心覆盖注册的事实。 In my experience it is in most cases much better to build up an incomplete container and add the missing registrations afterwards instead of overriding them. 根据我的经验,在大多数情况下,建立一个不完整的容器并在之后添加缺少的注册而不是覆盖它们会好得多。 Or if you decide to override, enable the feature at the last possible moment to prevent any accidental misconfigurations. 或者,如果您决定覆盖,请在最后一刻启用该功能,以防止任何意外的错误配置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM