4

根据文档,我可以使用激活事件来“将实例切换为另一个实例或将其包装在代理中”,但我无法让它工作。

这是我尝试过的:

[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 正在尝试转换ProxiedSampleSample实例,但事实并非如此。

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

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

4

1 回答 1

1

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构造函数发生更改,注册也必须更改,我通过具体类型的额外注册避免了这种情况。

于 2013-04-29T15:11:02.910 回答