C# 拦截在Ninject中创建实例

C# 拦截在Ninject中创建实例,c#,ninject,ninject-interception,C#,Ninject,Ninject Interception,我希望拦截实现特定接口或具有特定属性的实例的创建。我可以用截取扩展做一些类似的事情,但这似乎只做方法和属性截取 下面是我如何拦截方法和属性调用,但它不会拦截构造函数调用: _kernel.Bind<IInterceptor>().To<LogInterceptor>().InSingletonScope(); _kernel.Intercept(x => { if (x.Plan.Type.GetInterface(typeof(ITriggerLoggin

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

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

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

    return false;
}).With<LogInterceptor>();
\u kernel.Bind()To().InSingletonScope();
_kernel.Intercept(x=>
{
if(x.Plan.Type.GetInterface(typeof(itriggerginginterception.FullName)!=null)
{
返回true;
}
返回false;
}).带();

正如您自己所发现的,对于每个绑定,最接近于在实例上执行某些操作的是一个简单的过程,而不需要更改绑定

例如(示例取自:

您将手动使用此选项进行绑定:

kernel.Bind<FooViewModel>().ToSelf()
      .RegisterEvents()
      .InSingletonScope();
kernel.Bind().ToSelf()
.RegisterEvents()
.InSingletonScope();
(不需要
InSingletonScope()
,这只是为了表明您可以像以前一样使用其他绑定扩展/功能)


现在,我认为您应该采用这种“按约定”的方式。如果您按约定(ninject.extensions.conventions)创建绑定,您可以使用
IBindingGenerator
相应地创建绑定(无论是否调用
RegisterEvents
)。如果没有,那就更棘手了。我想说你必须扩展ninject的管道。

我一直在寻找,但仍然找不到方法,这通常是我试图做一些我不应该做的事情的迹象。你想通过拦截ctor实现什么?它需要多大的灵活性?这些可能是替代方法:
。ToProvider()
绑定或
.OnActivation()
绑定扩展。我正在开发一个基于插件的Caliburn Micro应用程序。我希望开发人员能够轻松利用一个eventAggregator组件。通常,为了使用该组件,必须插入eventAggregator并调用Subcribe()然后在其上实现IHandle接口,该接口告诉eventAggregator调用这些事件处理程序这很好,因为我可以看到开发人员忘记做这件事而浪费时间跟踪它。好的。绑定是谁/谁/什么时候创建的?我们使用了一个事件代理。用它注册发布者/订阅者是由一个定制的
RegisterBrokerEvents()完成的
extension扩展了ninject的
OnActivation
。这被称为post-ctor。绑定在两个地方创建。应用程序启动时绑定了logger factory之类的基本内容,然后在插件中循环,让每个插件都有机会添加自己的绑定。所以我想问题是,让它们将其连接在一起是否更好p在类或绑定中。仍然不是为他们实现的目标,但非常好。谢谢。很酷,我不知道那一个!你自己创建一个答案并接受它怎么样?我认为这可能是实现你想要的更好的方法。如果你只是编辑并将其放入answ,ninject wiki中也有一个条目er将涵盖所有可能性。但不幸的是,这不适合我,因为我也使用拦截。castle生成的代理没有实现与具体类型相同的接口,因此EventAggregator只是忽略了它。即使有肮脏的黑客攻击,也无法获得底层代理的目标。无法启用IHandle接口,因为并非所有实现都需要订阅。我认为开发人员只需自己订阅事件!@stom,这取决于绑定的范围。对于默认(
InTransientScope
)答案是从不。For(
InSingletonScope
)它是内核被释放的时候。对于其他人来说,它是作用域结束的时候——在这种情况下,它们可能会被延迟,因为根据使用情况,这只会被定期运行的后台作业检测到,后台作业会检查作用域
WeakReference
是否为活动的
。如果你实现了自己的作用域,你可以拥有针对确定性行为(它是一个Ninject接口),作用域对象实现
INotifyWhenDisposed
kernel.Components.Add<IActivationStrategy, StartableActivationStrategy>();
    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();