1

我希望拦截实现某个接口或具有某个属性的实例的创建。我可以做一些与拦截扩展类似的事情,但这似乎只做方法和属性拦截。

以下是我如何拦截方法和属性调用,但它不拦截构造函数调用:

_kernel.Bind<IInterceptor>().To<LogInterceptor>().InSingletonScope();
_kernel.Intercept(x =>
{
    if (x.Plan.Type.GetInterface(typeof(ITriggerLoggingInterception).FullName) != null)
    {
        return true;
    }

    return false;
}).With<LogInterceptor>();
4

1 回答 1

3

正如您自己发现的那样,最接近于对每个绑定进行实例化的操作(无需更改绑定)是IActivationStrategy

例如(取自此处的示例:

public class StartableStrategy : ActivationStrategy
{
  public override void Activate(IContext context, InstanceReference reference)
  {
    reference.IfInstanceIs<IStartable>(x => x.Start());
  }

  public override void Deactivate(IContext context, InstanceReference reference)
  {
    reference.IfInstanceIs<IStartable>(x => x.Stop());
  }
}

通过以下方式将其添加到 ninject 内核中:

kernel.Components.Add<IActivationStrategy, StartableActivationStrategy>();

替代 - 绑定语法糖

让我更详细地了解OnActivation()我在评论中提到的扩展:

    public static IBindingOnSyntax<T> RegisterEvents<T>(this IBindingOnSyntax<T> binding)
    {
        // todo check whether <T> implements the IHandle<> interface, if not throw exception
        return binding
            .OnActivation((ctx, instance) => ctx.Kernel.Get<EventAggregator>().Subscribe(instance));
    }

您将手动将其用于绑定:

kernel.Bind<FooViewModel>().ToSelf()
      .RegisterEvents()
      .InSingletonScope();

InSingletonScope()不需要 - 这只是为了表明您可以像以前一样使用其他绑定扩展/功能)。

现在我认为你想使用它而不是“按惯例”。如果您按照约定(ninject.extensions.conventions)创建绑定,则可以使用 anIBindingGenerator相应地创建绑定(无论是否调用RegisterEvents)。如果没有,那就更棘手了。我会说你必须扩展ninject的管道。

于 2015-01-15T17:23:44.740 回答