使用autofac&# 39;s的ReplaceInstance与接口类型

本文关键字:ReplaceInstance 接口类型 autofac 使用 | 更新日期: 2023-09-27 18:10:48

根据文档,我可以使用激活事件"将实例切换为另一个实例或将其包装在代理中",但我还没有能够让它工作。

这是我尝试过的:

[TestFixture]
public class ReplaceInstanceTest
{
    public interface ISample { }
    public class Sample : ISample { }
    public class ProxiedSample : ISample {
        private readonly ISample _sample;
        public ProxiedSample(ISample sample) {
            _sample = sample;
        }
    }
    [Test]
    public void ReplaceInstance_can_proxy_for_interface_type()
    {
        var builder = new ContainerBuilder();
        builder.RegisterType<Sample>()
               .As<ISample>()
               .OnActivating(x =>
                  x.ReplaceInstance(new ProxiedSample(x.Instance)))
               .SingleInstance();
        var container = builder.Build();
        var sample = container.Resolve<ISample>();
        Assert.That(sample, Is.InstanceOf<ProxiedSample>());
    }
}

上面的结果会导致一个类强制转换异常,因为autofacc试图将ProxiedSample强制转换为Sample实例,而它不是。

是否有可能在ActivatingEvent上使用ReplaceInstance来代理autofac(2.6或3.0)中的对象?

我知道可以使用RegisterDecorator,但是我的实际实现既配置代理又有条件代理,所以如果可能的话,我更喜欢使用激活事件。

使用autofac&# 39;s的ReplaceInstance与接口类型

Travis在autofac列表中详细回应了这方面的一些挑战。在他的评论和NSGaga的建议之间,我想出了以下解决办法:

[Test]
public void ReplaceInstance_can_proxy_for_interface_type_when_using_multi_stage_registration()
{
    var builder = new ContainerBuilder();
    builder.RegisterType<Sample>().AsSelf();
    builder.Register(c => (ISample)c.Resolve<Sample>())
           .OnActivating(x => x.ReplaceInstance(new ProxiedSample(x.Instance)))
           .SingleInstance();
    var container = builder.Build();
    var sample = container.Resolve<ISample>();
    Assert.That(sample, Is.InstanceOf<ProxiedSample>());
}

可以使注册更紧凑:

builder.Register<ISample>(c => new Sample()).OnActivating(/*...*/);
这种方法的缺点是,如果Sample构造函数改变,注册也必须改变,我通过对具体类型的额外注册来避免这种情况。