Search code examples
dependency-injectionspecflow

Specflow Dependency Injection doesn't update variables instantiated in BeforeScenario


Up until now, we've been using the dependency injection in Specflow to good effect - POCOs are instantiated automatically when needed, and carried from one steps binding to another with persisting data. However, I'm now looking to add something to the DI that is an instance of something that inherits an interface

[Binding]
public sealed class StepsFile
{
  private IFoo _foo;
  private BarClass _bar;
  
  public StepsFile(IFoo Foo, BarClass Bar)
  {
    _foo = Foo;
    _bar = Bar;
  }
  //Steps that do things with _foo and _bar
}

As this can't be instantiated directly, I've created a BeforeScenario to instantiate a class and RegisterInstanceAs the interface I'm using.

        [BeforeScenario]
        public void DIInitialiser()
        {
            var foo = new FooClass(){//init data};
            _objectContainer.RegisterInstanceAs<IFoo>(foo);
        }

This appears to work fine - the object is created and injected into my first steps binding, assigned to a local variable, which is then populated, etc.

The issue is when another steps binding is called

[Binding]
public sealed class AnotherStepsFile
{
  private IFoo _foo;
  private BarClass _bar;
  
  public AnotherStepsFile(IFoo Foo, BarClass Bar)
  {
    _foo = Foo;
    _bar = Bar;
  }
  //Different steps that do things with _foo and _bar
}

the instance of the interface injected is the same as was initially injected into the first file - the changed data that was written to the local variable wasn't written back to the injected variable, whereas the changes to _bar are reflected in the instance of Bar that is in AnotherStepsFile. Am I missing an AfterStep? Is what I'm trying possible, or do I need to gradually move away from ContextInjection to storing data in ScenarioContext? Would a 3rd party DI plugin do what I need?


Solution

  • The approach that I got working was to use ScenarioContext instead of DI. BeforeScenario looks the same as above, but Steps files now have

    [Binding]
    public sealed class StepsFile
    {
      private IFoo _foo
    {
        get => _scenarioContext.Get<IFoo >("FooObject");
        set => _scenarioContext.Set(value, "FooObject");
    }
      private BarClass _bar;
      
      public StepsFile(BarClass Bar)
      {
        _bar = Bar;
      }
      //Steps that do things with _foo and _bar
    }