Specflow依赖注入未更新BeforeScenario中实例化的变量问题
我们之前用SpecFlow的依赖注入效果很好,POCO类能按需自动实例化,数据也能在不同步骤绑定类之间持久化。现在需要注入接口实现类,于是在BeforeScenario中实例化FooClass,并通过RegisterInstanceAs注册IFoo接口实例。
但出现了问题:第一个步骤绑定类StepsFile注入该实例后修改了数据,可在另一个步骤绑定类AnotherStepsFile中,注入的IFoo实例还是初始状态,而BarClass实例的修改却能正常同步。
想请教几个问题:
- 是否缺少
AfterStep处理? - 这个需求是否可行?
- 是否需要从上下文注入转向使用
ScenarioContext存储数据? - 第三方DI插件能否解决此问题?
代码示例
StepsFile.cs
[Binding] public sealed class StepsFile { private IFoo _foo; private BarClass _bar; public StepsFile(IFoo Foo, BarClass Bar) { _foo = Foo; _bar = Bar; } // 操作_foo和_bar的步骤方法 }
DI初始化代码
[BeforeScenario] public void DIInitialiser() { var foo = new FooClass(){/* 初始化数据 */}; _objectContainer.RegisterInstanceAs<IFoo>(foo); }
AnotherStepsFile.cs
[Binding] public sealed class AnotherStepsFile { private IFoo _foo; private BarClass _bar; public AnotherStepsFile(IFoo Foo, BarClass Bar) { _foo = Foo; _bar = Bar; } // 操作_foo和_bar的其他步骤方法 }
问题解答
是否缺少
AfterStep处理?
不需要。AfterStep仅用于步骤执行后的清理或附加操作,和实例状态同步问题无关,核心问题出在DI实例的注册方式或生命周期配置上。这个需求是否可行?
完全可行。SpecFlow支持接口注入并保持场景内实例的状态同步,当前问题是注册逻辑或容器配置的细节导致的,并非需求本身不可实现。是否需要转向
ScenarioContext存储数据?
不是必须选项。ScenarioContext作为字典式存储,确实能实现步骤间数据共享,但类型安全性不如DI注入接口实例。如果追求代码整洁和类型安全,优先解决DI配置问题更合适;如果临时快速解决问题,可以用它作为替代方案。第三方DI插件能否解决此问题?
可以。SpecFlow默认的BoDi容器本身支持单实例注册,但如果遇到配置瓶颈,换用Autofac、Ninject等第三方DI插件,能提供更灵活的生命周期配置,确保IFoo实例在整个场景内保持单例,从而实现状态同步。
额外排查建议
- 确认
_objectContainer是SpecFlow的全局容器实例,避免在注册时意外创建了新容器; - 检查
FooClass是否为不可变类——如果修改数据时是创建新实例而非修改原有实例,后续注入的自然还是初始状态; - 尝试用
RegisterTypeAs<FooClass, IFoo>().InstancePerScenario()替代RegisterInstanceAs,让容器自动管理场景级单例,而非手动注册实例。
内容的提问来源于stack exchange,提问作者Ben E

