You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Autofac中IStartable.Start()先于RegisterBuildCallback执行:Bug还是特性?

IStartable.Start()先于RegisterBuildCallback执行:Bug还是特性?

咱们先直接聊核心结论:目前Autofac中这个执行顺序没有明确的官方定义,但从逻辑设计的角度来看,这属于不符合预期的行为——容器构建回调本就属于容器构建流程的一部分,可启动组件理应在容器完全构建完成、所有回调执行完毕后再启动。

依据Autofac官方文档的描述:

可启动组件(Startable Components):容器初始构建时会激活可启动组件

容器构建回调(Container Build Callbacks):可注册任意动作在容器构建时执行,回调会在容器从ContainerBuilder.Build返回前获取已构建的容器。

从文档描述来看,两者都属于容器构建阶段的操作,但官方没有明确规定执行顺序。不过从合理的流程逻辑出发,构建回调是对已构建容器的收尾操作,可启动组件的启动应该在所有构建相关操作完成后才触发,这样才能保证启动时容器的状态是完整的。

复现代码

using System; 
using Autofac; 

namespace AutofacBuildOrderRepro 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            var builder = new ContainerBuilder(); 
            builder.RegisterBuildCallback(ctx => StaticClass.ObjectProvider = () => new object()); 

            // 这段代码会抛出异常
            builder.RegisterType<StartableClass>().As<IStartable>().AsSelf().SingleInstance(); 
            builder.Build(); 

            // 这段代码可以正常运行
            //builder.RegisterType<StartableClass>().AsSelf().SingleInstance(); 
            //var container = builder.Build(); 
            //container.Resolve<StartableClass>().Start(); 
        } 

        class StartableClass : IStartable 
        { 
            public void Start() 
            { 
                StaticClass.Run(); 
            } 
        } 

        public static class StaticClass 
        { 
            public static Func<object> ObjectProvider { private get; set; } 

            public static void Run() 
            { 
                if (ObjectProvider == null) 
                { 
                    throw new InvalidOperationException("ObjectProvider is null"); 
                } 
                Console.WriteLine("Success"); 
            } 
        } 
    } 
}

异常调用栈

Unhandled Exception: Autofac.Core.DependencyResolutionException: An exception was thrown while executing a resolve operation. See the InnerException for details. ---> ObjectProvider is null (See inner exception for details.) ---> System.InvalidOperationException: ObjectProvider is null 
at AutofacBuildOrderRepro.Program.StaticClass.Run() in c:\path\AutofacBuildOrderRepro\Program.cs:line 39 
at AutofacBuildOrderRepro.Program.StartableClass.Start() in c:\path\AutofacBuildOrderRepro\Program.cs:line 27 
at Autofac.Core.Resolving.InstanceLookup.StartStartableComponent(Object instance) 
at Autofac.Core.Resolving.InstanceLookup.Execute() 
at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters) 
at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters) 
--- End of inner exception stack trace --- 
at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters) 
at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) 
at Autofac.Core.Container.ResolveComponent(IComponentRegistration registration, IEnumerable`1 parameters) 
at Autofac.Builder.StartableManager.StartStartableComponents(IComponentContext componentContext) 
at Autofac.ContainerBuilder.Build(ContainerBuildOptions options) 
at AutofacBuildOrderRepro.Program.Main(String[] args) in c:\path\AutofacBuildOrderRepro\Program.cs:line 15

测试使用的Autofac版本为4.8.1和3.0.4。

内容的提问来源于stack exchange,提问作者Grzegorz Smulko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:04:00