在 Ninject 中拦截创建实例
Intercept creation of instances in Ninject
我希望拦截实现特定接口或具有特定属性的实例的创建。我可以用拦截扩展做一些类似的事情,但这似乎只做方法和 属性 拦截。
以下是我如何拦截方法和 属性 调用,但它不会拦截构造函数调用:
_kernel.Bind<IInterceptor>().To<LogInterceptor>().InSingletonScope();
_kernel.Intercept(x =>
{
if (x.Plan.Type.GetInterface(typeof(ITriggerLoggingInterception).FullName) != null)
{
return true;
}
return false;
}).With<LogInterceptor>();
正如您自己发现的那样,最接近于对每个绑定执行实例化操作(无需更改绑定)的是 IActivationStrategy.
例如(示例取自here:
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()
- 它只是为了表明您可以像以前一样使用其他绑定 extensions/features)。
现在我认为你更想使用它 "by convention"。如果您按照约定 (ninject.extensions.conventions) 创建绑定,则可以使用 IBindingGenerator
相应地创建绑定(调用或不调用 RegisterEvents
)。如果没有,它会变得更加棘手。我会说你必须扩展 ninject 的管道。
我希望拦截实现特定接口或具有特定属性的实例的创建。我可以用拦截扩展做一些类似的事情,但这似乎只做方法和 属性 拦截。
以下是我如何拦截方法和 属性 调用,但它不会拦截构造函数调用:
_kernel.Bind<IInterceptor>().To<LogInterceptor>().InSingletonScope();
_kernel.Intercept(x =>
{
if (x.Plan.Type.GetInterface(typeof(ITriggerLoggingInterception).FullName) != null)
{
return true;
}
return false;
}).With<LogInterceptor>();
正如您自己发现的那样,最接近于对每个绑定执行实例化操作(无需更改绑定)的是 IActivationStrategy.
例如(示例取自here:
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()
- 它只是为了表明您可以像以前一样使用其他绑定 extensions/features)。
现在我认为你更想使用它 "by convention"。如果您按照约定 (ninject.extensions.conventions) 创建绑定,则可以使用 IBindingGenerator
相应地创建绑定(调用或不调用 RegisterEvents
)。如果没有,它会变得更加棘手。我会说你必须扩展 ninject 的管道。