域对象:
TargetObject.cs
public class TargetObject
{
public virtual ChildTargetObject ChildTargetObject
{
get { return ChildTargetObjectInner; }
set { ChildTargetObjectInner = value; }
}
public virtual ChildTargetObject ChildTargetObjectInner { get; set; }
}
配置和测试:
var settings = new NinjectSettings
{
InjectNonPublic = true,
AllowNullInjection = true
};
var kernel = new StandardKernel(settings);
kernel.Bind<TargetObject>().ToSelf();
kernel.InterceptReplaceSet<TargetObject>(t => t.ChildTargetObjectInner,
(inv) =>
{
inv.Proceed(); // <= we never step here. Why?
}
);
var o = kernel.Get<TargetObject>();
o.ChildTargetObject = new ChildTargetObject();
在最后一行中,我们更改了属性 ChildTargetObject ,它更改了内部属性 ChildTargetObjectInner 。但是我们没有拦截它。为什么呢?
如果我删除&#34;虚拟&#34;在 ChildTargetObject 附近它可以正常工作(但这种解决办法是不可能的,因为我使用NHiber)。
如果我直接更改 ChildTargetObjectInner ( ex,o.ChildTargetObjectInner = new ChildTargetObject(); ),我会拦截。
如何拦截任何变化(课堂上和课外)?谢谢。
答案 0 :(得分:0)
这是代理框架的限制以及ninject创建代理的方式。
如果您在该方法上获得virtual
,则该方法将被代理/拦截。但是,当您删除virtual
时,该方法将不再被代理/拦截。
现在显然,调用另一个(代理)方法的代理方法不会调用代理方法,而是调用实现。所以你不能拦截这些。
您可能正在使用城堡动态代理。 Krzysztof写了一篇关于它的very good tutorial,它还包括虚拟和非虚拟方法。
另请注意,由于您使用的是NHibernate,因此NHibernate也会创建代理。 现在,当您创建一个新实体时,您可以通过ninject创建它,它将代理它并配置拦截。 但是,当您从数据库中检索持久化实体时,它将由NHibernate创建。它也将代理并将其拦截器放在上面。但是它并不知道ninject的代理,因此不会添加这些拦截器。关于这一点,你可能想看看
或者您也可以使用Fody MethodDecorator
装饰您的方法