0

Domain object:

TargetObject.cs

    public class TargetObject
    {
        public virtual ChildTargetObject ChildTargetObject
        {
            get { return ChildTargetObjectInner; }
            set { ChildTargetObjectInner = value; }
        }

        public virtual ChildTargetObject ChildTargetObjectInner { get; set; }
    }

Configuration and test:

        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();

In the last line we have change property ChildTargetObject and it change inner property ChildTargetObjectInner. But we didnt get interception of it. Why?

If I remove the "virtual" near ChildTargetObject it will be work fine (but this workaround impossible because I use NHiber).

If I change ChildTargetObjectInner directly (ex, o.ChildTargetObjectInner = new ChildTargetObject();), I got intercept.

How can I intercept of any changes (in class and out of class)? Thank you.

4

1 回答 1

0

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

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

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

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

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


或者,您也可以使用Fody MethodDecorator装饰您的方法

于 2014-07-07T08:29:09.483 回答