微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – Autofac:如何限制IDisposable对象的生命周期,而不会绕过IoC容器

我正在学习如何使用Autofac,并且我坚持确定性地处理Idisposable对象.我先说明一下情况,然后再说明我的问题.

起始位置:

假设我的对象模型是通过以下接口定义的:

interface IApple : Idisposable
{
    void Consume();
}

interface IHorse
{
    void Eat(IApple apple);   // is supposed to call apple.Consume()
}

interface IHorseKeeper
{
    void FeedHorse();   // is supposed to call horse.Eat(apple)
                        //   where 'horse' is injected into IHorseKeeper
                        //   and 'apple' is generated by IHorseKeeper on-the-fly
}

此外,我定义一个将用作IApple工厂的代理:

delegate IApple AppleFactory;

自动配置配置:

现在,我将注册以上类型如下 – 请注意,我省略了Apple和Horse两类的代码,因为它们实现起来很简单:

var builder = new Autofac.ContainerBuilder();

builder.RegisterType<Apple>().As<IApple>();
builder.RegisterType<Horse>().As<IHorse>();
builder.RegisterType<HorseKeeper>().As<IHorseKeeper>();
builder.RegisterGeneratedFactory<AppleFactory>();

我的问题:

我不太了解如何实现IHorseKeeper.Feed方法.这是我目前拥有的:

class HorseKeeper : IHorseKeeper
{
    private readonly IHorse horse;
    private readonly AppleFactory appleFactory;

    public HorseKeeper(IHorse horse,AppleFactory appleFactory)
    //                 ^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^^
    //                         constructor injection
    {
        this.horse = horse;
        this.appleFactory = appleFactory;
    }

    public void FeedHorse()
    {
        using (var apple = appleFactory())
        {
            horse.Eat(apple);
        }  // <- dispose() apple Now (ASAP),as it's no longer needed!
    }
}

这是我想要的那种代码,因为它完全是Autofac-agnostic.只要AppleFactory可以按预期工作,它可以与另一个IoC容器一起工作.

然而,由于Autofac为我处理AppleFactory,它将跟踪它为我生成的所有IApple对象,因此将在容器的生命周期结束时自己处理它们.也就是说,生产的苹果将被处理两次.

我想将IApple注册为.ExternallyOwned()不是可行的解决方案,因为可能会更容易让Autofac处理IApples的生命周期.

Deterministic disposal with Autofac需要使用container.BeginLifetimeScope()创建一个嵌套的容器,但是我不想在HorseKeeper.FeedHorse中使用它,因为这样HorseKeeper将依赖于Autofac,我想保持我的代码IoC-agnostic.

题:

如何在IoC(Autofac)诊断方式下实现HorseKeeper.FeedHorse,同时确保即时生成的对象被正确放置?

解决方法

其他答案在这里是有洞察力的,但有一个问题.在这两种情况下,如果苹果有其他依赖需要处理,则不会发生正确的清理.

Autofac 2提供了一个新的功能来帮助这里称为“拥有的实例”.我注意到你的注册码是Autofac 1.4,所以如果你无法升级让我知道(还有其他的,透明度较低的方法)

像往常一样注册苹果(不是外部拥有的):

builder.RegisterType<Apple>().As<IApple>();

将AppleFactory声明为:

public delegate Owned<IApple> AppleFactory();

在Autofac 2中,您不需要再调用RegisterGeneratedFactory() – 这是自动的.

然后,在HorseKeeper,喂马像这样:

public void FeedHorse()
{
    using (var apple = appleFactory())
    {
        horse.Eat(apple.Value);
    }
}

(注意.Value属性获取底层的IApple.

在使用块的末尾,苹果加上其所有依赖项,将被清理掉.

直接使用IApple(作为依赖)的任何其他组件将获得通常的行为.

原文地址:https://www.jb51.cc/csharp/96520.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐