Specflow.Autofac: 容器构建完成后换出一个依赖

Specflow.Autofac: Swap out a dependency after the container has been built

仅供参考:我正在使用 SpecFlow.Autofac nuget 包。

父 class 库项目中存在以下 GetContainer 方法。

    [ScenarioDependencies]
    public static ContainerBuilder GetContainerWithDependencies()
    {
        var containerBuilder = new ContainerBuilder();

        containerBuilder.RegisterType<PosMgmtScenarioCtx>().As<IScenarioContext>().InstancePerLifetimeScope();

        return containerBuilder;
    }

稍后,在子项目(引用父项目)中,我尝试用新的 class 替换接口实现,但它不起作用。

    [Given(@"...Step...")]
    public void GivenGenerateEmpWithXRefCode(some params)
    {
        using 
        (
            var scope = _lifetimeScope.BeginLifetimeScope(
                builder =>  {
                    // THIS DOES NOT WORK.
                    builder.RegisterType<EmployeeScenarioCtx>().As<IScenarioContext>();
                }
            )
        )
        {                
            _createUpdatePositionStepsLogic.PostPatchTheObject(service, "POST", "Employee", url, expectedStatusCode,
                version);
        }
    }

需要将 IScenarioContext 替换为 EmployeeScenarioCtx 而不是 PosMgmtScenarioCtx。

任何帮助将不胜感激,谢谢!

您应该使用您创建的范围来解除依赖。

var createUpdatePositionStepsLogic = scope.Resolve<...>();

原来的依赖已经全部解析,所以您需要使用新的范围重新解析它们才能使用新的注册。

所以,我的问题应该是如何使用 Autofac 覆盖构造函数中的依赖项,对此已经有很多答案。我没有将我的问题标记为重复的声誉,但请在必要时这样做。

以下答案对我有帮助:

最终代码现在是这样的:

using(var scope = _lifetimeScope.BeginLifetimeScope(
                builder =>
                {
                    builder.RegisterType<WithPayload>().WithParameter(
                        (p, c) => p.ParameterType == typeof(IScenarioContext),
                        (p, c) => c.Resolve<EmployeeScenarioCtx>()).As<IWithPayload>();
                }
            )
        )
        {
            switch (version)
            {
                case PosMgmtStepsVersion.V1:
                    var withPayload = scope.Resolve<IWithPayload>();
                    withPayload.GivenPOST_PATCH_EndPoint_WithStatusCodeCheck("POST", "Employee", UniqueIdentifier,
                        url,
                        expectedStatusCode);
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(version), version, null);
            }