【发布时间】:2010-11-27 11:26:38
【问题描述】:
我在我的项目中使用 Castle Windsor。一些注册的组件被拦截。因为组件是通过接口注册的,Castle Windsor 创建了接口代理(Castle Windsor 创建了一个独立的类型,它实现了接口并通过使用组合委托给真正的实现)。不幸的是,您无法在接口的实际实现中执行方法,因为代理会被绕过。
有没有办法在实际实现中获取代表实际实现的代理实例?
这是我想要实现的一个示例。我想总是拦截 Get 方法。请不要使用其他方法来重构此示例,因为这不是我的生产代码,而只是为了演示而发明的东西。
public interface IProvider
{
bool IsEmpty { get; }
object Get();
}
public class ProxyBypassingProvider : IProvider
{
public bool IsEmpty
{
// Calls method directly, not through the proxy.
get { return Get() == null; }
}
public object Get()
{
return new Object();
}
}
public class InterceptedProvider : IProvider
{
private IProvider _this; // Should hold the proxy instance.
public bool IsEmpty
{
// Calls method through proxy.
get { return _this.Get() == null; }
}
public object Get()
{
return new Object();
}
}
如何将字段 _this 设置为代理实例?
最好的问候
奥利弗·哈纳皮
PS:这是一个真实的例子。
public interface IPresentationModel
{
IView View { get; }
}
public interface IView
{
void SetModel(IPresentationModel model);
}
public PresentationModel : IPresentationModel
{
public IView View { get; private set; }
public PresentationModel(IView view)
{
View = view;
View.SetModel(this);
}
}
我正在解决一个瞬态演示模型。它会注入一个瞬态视图。因为视图需要知道表示模型,所以表示模型调用 IView.SetModel(this) 让视图知道它的表示模型。
现在的问题是,虽然解析的 IPresentationModel 是一个代理,但 SetModel 方法只获得真正的实现。因此,当视图调用表示模型上的方法时,不会触发任何拦截器。
到目前为止,我找到的唯一解决方案是在解析了我的演示模型后手动设置视图的演示模型。
var model = _container.Resolve<IPresentationModel>();
model.View.SetModel(model);
我认为,这个解决方案并没有真正解决得很好。
【问题讨论】:
-
看起来你把事情复杂化了,但我不确定,因为我不完全理解你想要实现的目标......你能发布更多关于你的潜在问题的细节吗?
-
嗨!我不认为,我让事情变得更复杂。我只想使用拦截器。当某些对象解析 IProvider 时,它不会获得已注册组件的实例,而是获得实现 IProvider 的动态创建的类的实例。此类将每个请求转发给真正的实现,但会拦截请求。当真实实现调用接口方法时,调用不会经过动态创建的代理,而是直接调用真实方法。因此不会调用任何拦截器。希望,现在更清楚一点;)
标签: c# proxy castle-windsor castle-dynamicproxy