如何修改Autofac默认行为?自定义disposables托管策略
解决Autofac默认持有Instance Per Dependency可释放实例的问题
嘿,这个问题我之前也碰到过——手动给每个Instance Per Dependency模式的可释放注册加ExternallyOwned()确实太繁琐了,还好Autofac留了扩展点,能实现全局默认配置,不用再重复劳动!
核心思路
我们可以利用Autofac的注册回调机制,遍历所有注册项,自动为符合条件的注册(Instance Per Dependency生命周期+实现IDisposable的类型)设置ExternallyOwned,而其他生命周期(InstancePerLifetimeScope/SingleInstance)的实例依然由Autofac负责释放。
具体实现代码
直接在构建容器前添加全局注册回调即可:
var builder = new ContainerBuilder(); // 全局处理所有注册的回调 builder.RegisterCallback(componentRegistry => { foreach (var registration in componentRegistry.Registrations) { // 筛选条件:默认生命周期(InstancePerDependency)+ 可释放类型 if (registration.Lifetime is CurrentScopeLifetime && registration.Activator.LimitType.IsAssignableTo(typeof(IDisposable))) { // 将实例所有权设为外部拥有,Autofac不再持有并释放 registration.Ownership = InstanceOwnership.ExternallyOwned; } } }); // 你的业务注册代码示例 builder.RegisterType<TransientDisposableService>(); // 自动应用ExternallyOwned builder.RegisterType<ScopedDisposableService>().InstancePerLifetimeScope(); // 不受影响,Autofac管理释放 builder.RegisterType<SingletonDisposableService>().SingleInstance(); // 不受影响,Autofac管理释放 var container = builder.Build();
关键细节说明
CurrentScopeLifetime是Autofac内部对应InstancePerDependency(瞬时模式)的生命周期类型,默认注册不指定生命周期时就用这个。- 如果有个别瞬时注册你不想应用这个规则,只需要手动在注册时覆盖即可,比如:
手动设置的所有权会优先于全局回调的配置。builder.RegisterType<SpecialTransientService>().InstancePerDependency().OwnedByLifetimeScope(); - 对于
InstancePerLifetimeScope或SingleInstance的注册,它们的生命周期类型不是CurrentScopeLifetime,所以不会被修改,依然保持Autofac默认的持有并释放逻辑,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Yair Halberstadt
相关产品推荐
相关产品推荐

