5

Ninject と Interceptor パターンの使い方を学んでいます。

次のインターセプターがあります。

public class MyInterceptor:IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine("Pre Execute: " + invocation.Request.Method.Name);

        foreach (var param in invocation.Request.Arguments)
        {
            Console.WriteLine("param : " + param);
        }

        invocation.Proceed();

        Console.WriteLine("Post Execute: " + invocation.Request.Method.Name);
        Console.WriteLine("Returned: " + invocation.ReturnValue);
    }
}

MyClassそして、インターセプターがそれらで動作できるようにするために、仮想の2つの単純なメソッドしか持たないという名前のクラスを用意します。(2 つのメソッドは Echo と double で、その名前が示すとおりです。)

Ninject、Ninject.Extensions.Interception、Ninject.Extensions.Interception.DynamicProxy を NuGet 経由でプロジェクトに追加しました。

using次のステートメントを追加しました。

using Ninject;
using Ninject.Extensions.Interception.Infrastructure.Language;
using Ninject.Extensions.Interception;

ブートストラップを行う私の Main メソッドは次のようになります。

static void Main(string[] args)
    {
        MyClass o = null;

        using (IKernel kernel = new StandardKernel())
        {

            kernel.Bind<MyClass>().ToSelf().Intercept().With(new MyInterceptor());
            o = kernel.Get<MyClass>();
        }

        o.Echo("Hello World!"); // Error
        o.Double(5);
    }

指定した行で次のエラーが発生します。

Error loading Ninject component IProxyRequestFactory
No such component has been registered in the kernel's component container.

Suggestions:
  1) If you have created a custom subclass for KernelBase, ensure that you have  properly
     implemented the AddComponents() method.
  2) Ensure that you have not removed the component from the container via a call to RemoveAll().
  3) Ensure you have not accidentally created more than one kernel..

誰が私が間違っているのか教えてもらえますか?

4

1 に答える 1

5

OK、ようやく再現できました (MyClass メソッドを仮想化するのを忘れていました)。私がそれを解決した方法は、カーネルの周りから using ブロックを削除することでした:

    static void Main(string[] args)
    {
        MyClass o = null;

        var kernel = new StandardKernel();
        kernel.Bind<MyClass>().ToSelf().Intercept().With(new MyInterceptor());
        o = kernel.Get<MyClass>();

        o.Echo("Hello World!"); // Error
        o.Double(5);
        Console.ReadKey(true);
    }

これが機能すると私が推測している理由は、カバーの下でプロキシクラスを作成しMyClass、何らかのIKernel方法でプロキシに渡すためです。メソッドを (プロキシで) 呼び出すと、カーネルに戻り、いくつかの追加の依存関係 (を含むIProxyRequestFactory) を解決します。あなたがそれを処分していたので、その依存関係を解決できなくなりました。

于 2012-08-23T00:34:41.373 に答える