[Autofac:需要:AutofacModule中处理的实例的生命周期终止事件

问题描述 投票:1回答:1

我使用C#和Autofac 4.9.4。我有一个连接到IComponentRegistration.Activated事件的Autofac模块。它查找某些类的激活实例,并将它们注册到某个管理器类中。当然,这种注册应仅限于受影响对象的寿命。因此,模块需要知道何时容器将对象丢弃,然后从管理器中注销它。否则会产生内存泄漏。当我在autofac ContainerBuilder中注册一个类时,有一个OnRelease-Method,但这不是正确的位置。我在模块中需要这样的事件。

具体代码看起来像这样:

using Autofac;
using Autofac.Core;

namespace De.Gedat.Foundation.Bl.IoC
{

    public class ResetManagerModule : Module
    {
        protected override void AttachToComponentRegistration(
            IComponentRegistry componentRegistry,
            IComponentRegistration registration)
        {
            registration.Activated += (sender, e) =>
                RegisterToResetManager(e.Instance, e.Context);
            registration.Released += ???
        }

        private void RegisterToResetManager(object instance, IComponentContext context)
        {
            // Every IAutoRegisteredResettable object created by IoC will be picked up:
            var resettable = instance as IAutoRegisteredResettable;
            if (resettable == null)
                return;
            // Get the singleton IResetManager...
            var resetManager = context.Resolve<IResetManager>();
            // ...and register the instance with it:
            resetManager.RegisterInstance(resettable);

            // ...and on resettable's end-of-lifetime we would have to call:
            //resetManager.UnregisterInstance(resettable)
            //...but not at this point when the instance has just been created!
        }
    }
}

如何丢弃对象时会引起注意?

object-lifetime autofac-module lifetime-scoping
1个回答
0
投票

[假设存在生命周期的范围,我们本来希望让autofac为我们处理所有处置,所以最好使用using语句包装上下文,但是它也将处置resettable,因此我们将无法处置致电resetManager.UnregisterInstance(resettable)

[为了不处置您的resettable实例,并在处置生存期范围时仍让autofac处理所有处置,我们可以使用ExternallyOwneddoc告诉我们要自己处理它: ,然后在finally语句中调用resetManager.UnregisterInstance(resettable),然后手动处理实例。

private void RegisterToResetManager(object instance, IComponentContext context)
{
    var resettable = instance as IAutoRegisteredResettable;
    if (resettable == null)
        return;
    var resetManager = context.Resolve<IResetManager>();

    try
    {
        resetManager.RegisterInstance(resettable).ExternallyOwned();
    }
    finally
    {
        resetManager.UnregisterInstance(resettable);
        resettable.Dispose();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.