Ninject。对内部集合属性的奇怪拦截

时间:2014-07-06 06:28:50

标签: c# ninject ninject-interception

域对象:

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(); ),我会拦截。

如何拦截任何变化(课堂上和课外)?谢谢。

1 个答案:

答案 0 :(得分:0)

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

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

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

您可能正在使用城堡动态代理。 Krzysztof写了一篇关于它的very good tutorial,它还包括虚拟和非虚拟方法。

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


或者您也可以使用Fody MethodDecorator

装饰您的方法