根据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
实例,但事实并非如此。
是否可以在 ActivatingEvent 上使用 ReplaceInstance
在 autofac(2.6 或 3.0)中代理一个对象?
我知道可以使用 RegisterDecorator ,但我的实际实现同时配置和有条件地代理,所以如果可能的话,我更愿意使用激活事件。
最佳答案
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
构造函数更改,注册也必须更改,我通过具体类型的额外注册避免了这种情况。
关于c# - 将 Autofac 的 ReplaceInstance 与接口(interface)类型一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16218946/