Simple Injector, can't override existing registration

左心房为你撑大大i 提交于 2019-11-30 14:18:42

Replacing an existing registration after you already worked with the container hardly ever has the behavior you would expect (and this holds for all DI libraries) and that's the reason why the Simple Injector container is locked. This is described in more details here (as @qujck already pointed out).

First of all, if you are writing unit tests, you shouldn't use a container at all. Your unit tests should create the class under test themselves, or you extract this logic to a convenient factory method, such as:

private static MailNotifier CreateMailNotifier(
    IDeposit deposit = null, ISendMail mailSender = null, ILog logger = null)
{
  return new MailNotifier(
      deposit ?? Substitute.For<IDeposit>(),
      mailSender ?? Substitute.For<ISendMail>(),
      logger ?? Substitute.For<ILog>());
}

This factory method is a variation to the Test Data Builder pattern.

By making use of optional parameters, it allows the unit test to specify only the fake implementation it requires during testing:

public void Notify_WithValidUser_LogsAMessage()
{
    // Arrange
    var user = new User();

    var logger = new FakeLogger();

    MailNotifier sut = CreateMailNotifier(logger: logger);

    // Act
    sut.Notify(user);

    // Assert
    Assert.AreEqual(expected: 1, actual: logger.LoggedMessages.Count);
}

If you use a container, because creating the class under test by hand is too cumbersome, it indicates a problem in your class under test (most likely a Single Responsibility Principle violation). Prevent using tools to work around problems in your design; your code is speaking to you.

For integration tests however, it is much more usual to use the container, but in that case you should simply create a new container for each integration test. This way you can add or replace the IWebServiceOrder without any problem.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!