DryIoc:能否将已创建对象注册为单例并复用?
如何让DI容器解析出已提前创建的单例实例?
嘿,我完全懂你的需求——提前手动创建好MyObject的实例,然后让DI容器每次解析IMyObject时都返回这个现成的实例,而不是自己再新建一个对吧?你之前尝试的方式没成功是正常的,因为大部分DI容器的常规泛型注册方法,并不会把你传入的实例当成单例的“蓝本”,而是依旧会自己创建新实例。
问题出在哪?
你写的这段代码:
var myObjectInstance = new MyObject(); Container.Register<IMyObject, MyObject>(Reuse.Singleton, myObjectInstance); var myObjectInstance2 = Container.Resolve<IMyObject>();
这里的第二个参数myObjectInstance,在多数DI容器的重载逻辑里,并不是用来指定“要用这个现成实例当单例”,而是用于传递构造函数参数、注册元数据这类额外选项。所以容器还是会按照常规单例流程,自己新建一个MyObject实例,导致myObjectInstance2和你提前创建的实例引用不相等。
正确的做法(主流DI容器示例)
不同的DI容器都有专门的方法来注册已存在的实例,而不是让容器自己创建:
1. Autofac
用RegisterInstance方法直接注册你的实例,这个方法本身就代表该实例是单例:
var myObjectInstance = new MyObject(); // 注册现有实例,明确标记为单例 Container.RegisterInstance<IMyObject>(myObjectInstance).SingleInstance(); // 解析时直接返回你创建的实例 var myObjectInstance2 = Container.Resolve<IMyObject>(); // 此时 myObjectInstance2 == myObjectInstance 结果为 true
2. Microsoft.Extensions.DependencyInjection(原生DI)
使用AddSingleton的实例重载版本:
var services = new ServiceCollection(); var myObjectInstance = new MyObject(); // 直接把现成实例传入AddSingleton services.AddSingleton<IMyObject>(myObjectInstance); var container = services.BuildServiceProvider(); var myObjectInstance2 = container.GetRequiredService<IMyObject>(); // 两者引用完全相同
额外注意事项
- 一旦把实例交给DI容器管理,容器会负责它的生命周期(比如当容器释放时,如果实例实现了
IDisposable,容器会自动调用其Dispose方法),所以不要自己手动释放这个实例,避免双重释放的问题。 - 如果这个实例会被多线程共享,要确保它的状态修改是线程安全的,毕竟单例实例会被所有解析它的地方共用。
内容的提问来源于stack exchange,提问作者Talha ZENGİN
相关产品推荐
相关产品推荐

