C# 为什么Ninject绑定和拦截返回接口代理?

C# 为什么Ninject绑定和拦截返回接口代理?,c#,ninject,fluorinefx,ninject-interception,C#,Ninject,Fluorinefx,Ninject Interception,我试图理解Ninject.Extensions.Interception3.0.0.8是如何为我的类构建动态代理的。我发现,当我用继承自InterceptAttribute的属性装饰我的具体类时,或者当我在绑定时用Intercept()方法直接拦截时,Ninject返回装饰类的动态代理,而不是普通类型 我有一个IPolicySearchPresenter接口,我正在绑定到FlexPolicySearchPresenter具体类型,添加一个异常记录器拦截器: Bind<IExceptionI

我试图理解
Ninject.Extensions.Interception
3.0.0.8是如何为我的类构建动态代理的。我发现,当我用继承自
InterceptAttribute
的属性装饰我的具体类时,或者当我在绑定时用
Intercept()
方法直接拦截时,Ninject返回装饰类的动态代理,而不是普通类型

我有一个
IPolicySearchPresenter
接口,我正在绑定到
FlexPolicySearchPresenter
具体类型,添加一个异常记录器拦截器:

Bind<IExceptionInterceptor>().To<ExceptionInterceptor>();
Bind<IPolicySearchPresenter>().To<FlexPolicySearchPresenter>().Intercept().With<IExceptionInterceptor>();
返回的类型返回为
Castle.proxy.FlexPolicySearchPresenterProxy
,与我的远程处理实现完美配合

问题是,如何获取Ninject.Interception返回我
FlexPolicySearchPresenterProxy
的实例,而不是
IPolicySearchPresenterProxy
。 请注意,通过手动方式,我以不同的方式绑定:

        Bind(interfaceType).ToConstant(proxy).InThreadScope();
与ninject方式不同:

Bind<IPolicySearchPresenter>().To<FlexPolicySearchPresenter>().Intercept().With<IExceptionInterceptor>();
Bind().To().Intercept().With();

我是否需要更改在Ninject中进行绑定的方式以获得正确的类型?

编辑:向Foo添加了属性注入

我有一个有效的解决方案给你,但老实说,我不是100%满意。无论如何,这是可行的:

class Program
{
    static void Main(string[] args)
    {
        var kernel = new StandardKernel();
        kernel.Bind<IFoo>().ToMethod(ctx => ctx.Kernel.Get<Foo>());

        kernel.Bind<Foo>().ToSelf().Intercept().With<SomeInterceptor>();

        var foo = kernel.Get<IFoo>();

        foo.DoSomething();

        Console.WriteLine(foo.GetType());

        Console.Read();
    }
}

public interface IFoo
{
    void DoSomething();
}

public class Foo : IFoo
{
    [Inject]
    public Bar Dependency { get; set; }

    public virtual void DoSomething()
    {
        Console.WriteLine("doing something with {0}", this.Dependency);
    }
}

public class SomeInterceptor : IInterceptor
{
    public SomeInterceptor()
    {
        Console.WriteLine("interceptor created");
    }

    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine("before");
        invocation.Proceed();
        Console.WriteLine("after");
    }
}

public class Bar
{
    public override string ToString()
    {
        return "Bar (injected dependency)";
    }
}
类型为:

Castle.Proxies.FooProxy
似乎.Bind().To()和.Bind().ToSelf().Intercept。。。没有相同的结果。我还不知道为什么——但也许我会去调查一下

构造函数参数更新: Ninject本身只支持“基于继承的类代理”——类需要一个默认/空的ctor和“没有目标的接口代理”——这是您不想要的

因此,您是否可以“仅此一次”使用属性注入? 否则,您将需要创建自己的拦截ninject magic并使用“带目标的类代理”(请参阅) 备注:尽管“带目标的类代理”支持构造函数参数,但您需要事先知道它们是什么(因此不容易获得DI支持)。
(在动态代理选择/创建代理的构造函数之后,我没有找到解析构造函数参数的钩子。)

您是否尝试过从IPolicy创建绑定。。到FlexPolicy,然后将FlexPolicy.ToSelf().Intercept()绑定到?(旁注:ninject Instances拦截器每种类型一次,而不是每一个代理实例一次)。今天早上我要试一试。谢谢你的建议我这么做了:
Bind().To()
Bind().ToSelf().Intercept().With()
var proxy=Kernel.Get()但代理返回为
FlexPolicySearchPresenter
类型,而不是
FlexPolicySearchPresenterProxy
,拦截没有启动:(奇怪。是否有任何虚拟方法@FlexPolicySearchPresenter?顺便说一句,以下是动态代理实例的ninject扩展代码:(注意if(targetType.IsInterface))是的,我的演示者中有一个虚拟方法,我在其中抛出一个异常,以便我的拦截器管理它。我从NuGet下载了我正在使用的版本的Ninject.Extensions.Interception源代码,但无法将调试器附加到该源代码,这将使事情更加清楚……我的Visual Studio恢复活力后,我将尝试它。谢谢r您的帮助!对我不起作用。我收到以下错误:“找不到无参数构造函数”。我的FlexPolicySearchPresenter有点复杂,有构造函数注入:
public FlexPolicySearchPresenter(IPolicySearchService policySearchServiceService,IUserAuthorizationService IUserAuthorizationService):基本(IUserAuthorizationService){U policySearchService=policySearchServiceService;}
是的,它来自Castle.DynamicProxy:at Castle.DynamicProxy.ProxyGenerator.CreateClassProxyInstance(类型proxyType,列出'1个proxyArguments,类型classToProxy,类型Object[]constructorArguments)at Castle.dynamicproxygenerator.createClassProxyProxy(类型classToProxy,类型[]Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(键入classToProxy,ProxyGenerationOptions,Object[]constructorArguments,IIInterceptor[]Interceptor)上的additionalInterfacesToProxy,ProxyGenerationOptions,Object[]constructorArguments,IIInterceptor[]Interceptor[]Interceptor)选项见更新答案的底部,以了解有关“空构造函数”问题。谢谢@BatteryBackupUnit。在这一点上,我不认为属性注入是一个选项,我们正在尝试远离它。我通过Castle libs手动创建类代理的方式目前运行良好。但我想通过Ninject扩展包装完成这项工作。
class Program
{
    static void Main(string[] args)
    {
        var kernel = new StandardKernel();
        kernel.Bind<IFoo>().ToMethod(ctx => ctx.Kernel.Get<Foo>());

        kernel.Bind<Foo>().ToSelf().Intercept().With<SomeInterceptor>();

        var foo = kernel.Get<IFoo>();

        foo.DoSomething();

        Console.WriteLine(foo.GetType());

        Console.Read();
    }
}

public interface IFoo
{
    void DoSomething();
}

public class Foo : IFoo
{
    [Inject]
    public Bar Dependency { get; set; }

    public virtual void DoSomething()
    {
        Console.WriteLine("doing something with {0}", this.Dependency);
    }
}

public class SomeInterceptor : IInterceptor
{
    public SomeInterceptor()
    {
        Console.WriteLine("interceptor created");
    }

    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine("before");
        invocation.Proceed();
        Console.WriteLine("after");
    }
}

public class Bar
{
    public override string ToString()
    {
        return "Bar (injected dependency)";
    }
}
interceptor created
before
doing something with Bar (injected dependency)
after
Castle.Proxies.FooProxy