Ninject.内部集合属性的奇怪截距



域对象:

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。但是我们没有拦截它。为什么?

如果我删除ChildTargetObject附近的"虚拟",它将工作得很好(但这个解决方案不可能,因为我使用NHiber)。

如果我直接改变ChildTargetObjectInner (ex, o.ChildTargetObjectInner = new ChildTargetObject();),我得到了拦截。

我如何拦截任何更改(类内和类外)?谢谢你!

这是代理框架和ninject创建代理的方式的限制。

如果方法上有virtual,则该方法将被代理/拦截。但是,当您删除virtual时,该方法将不再被代理/拦截。

现在很明显,一个被代理的方法调用另一个(被代理的)方法将不会调用被代理的方法,而是调用实现。所以你不能截取这些

您可能正在使用castle动态代理。Krzysztof写了一个非常好的教程,它还涵盖了虚拟和非虚拟方法。

还要注意,因为你使用的是NHibernate, NHibernate也会创建代理。现在,当您创建一个新实体时,您可以通过ninject创建它,它将代理它并配置拦截。然而,当你从数据库中检索持久化实体时,它将由NHibernate创建。它也会代理它,并把它的拦截器放在上面。但是它不知道ninject的代理,因此不会添加这些拦截器。关于这一点,您可以查看

  • http://nhibernate.info/blog/2008/12/12/entities-behavior-injection.html
  • http://blog.scooletz.com/2011/02/14/nhibernate-interceptor-magic-tricks-pt-3/

或者你也可以使用Fody MethodDecorator

来装饰你的方法

相关内容

  • 没有找到相关文章

最新更新