将Autofac的ReplaceInstance与接口类型一起使用

时间:2013-04-25 15:33:27

标签: c# autofac

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

以下是我尝试的内容:

[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>());
    }

}

上述结果导致了类强制转换异常,因为autofac正在尝试将ProxiedSample强制转换为Sample实例,而不是。{/ p>

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

我知道可以使用RegisterDecorator,但我的实际配置包括配置和条件代理,因此我更愿意使用激活事件,如果可能的话。

1 个答案:

答案 0 :(得分:1)

Travis在autofac列表detailing some of the challenges surrounding this上回复。在他的评论和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构造函数更改,则注册也必须更改,我通过额外注册具体类型避免了这种情况。