8

ファクトリを使用してデータセンダーを返しています。

Bind<IDataSenderFactory>()
    .ToFactory();

public interface IDataSenderFactory
{
    IDataSender CreateDataSender(Connection connection);
}

私は、異なるタイプを取る datasender (WCF とリモーティング) の 2 つの異なる実装を持っています。

public abstract class Connection
{
    public string ServerName { get; set; }
}

public class WcfConnection : Connection
{
    // specificProperties etc.
}

public class RemotingConnection : Connection
{
    // specificProperties etc.
}

パラメータから渡された Connection のタイプに基づいて、Ninject を使用してこれらの特定のタイプのデータセンダをバインドしようとしています。私は次のことを試みましたが失敗しました:

Bind<IDataSender>()
    .To<RemotingDataSender>()
    .When(a => a.Parameters.Single(b => b.Name == "connection") as RemotingConnection != null)

これは、「.When」が要求のみを提供し、実際のパラメーター値を取得してその型を確認できるように完全なコンテキストが必要になるためだと思います。名前付きバインディングを使用する以外に、実際にファクトリを実装してそこにロジックを配置する以外に、何をすべきか途方に暮れています。

public IDataSender CreateDataSender(Connection connection)
{
    if (connection.GetType() == typeof(WcfConnection))
    {
        return resolutionRoot.Get<IDataSender>("wcfdatasender", new ConstructorArgument("connection", connection));
    }

    return resolutionRoot.Get<IDataSender>("remotingdatasender", new ConstructorArgument("connection", connection));
}
4

1 に答える 1

7

Ninject のソースをいくつか調べたところ、次のことがわかりました。

  • a.Parameters.Single(b => b.Name == "connection")IParameter実際のパラメーターではなく、タイプの変数を提供します。

  • IParameternull でないコンテキスト パラメータを必要とするメソッドobject GetValue(IContext context, ITarget target)があります (ターゲットは null にすることができます)。

  • Request から IContext を取得する方法が見つかりませんでした (サンプルの変数 a)。

  • Contextクラスにはパラメーターなしのコンストラクターがないため、新しい Context を作成できません。

それを機能させるには、次のようなダミーの IContext 実装を作成できます。

public class DummyContext : IContext
{
    public IKernel Kernel { get; private set; }
    public IRequest Request { get; private set; }
    public IBinding Binding { get; private set; }
    public IPlan Plan { get; set; }
    public ICollection<IParameter> Parameters { get; private set; }
    public Type[] GenericArguments { get; private set; }
    public bool HasInferredGenericArguments { get; private set; }
    public IProvider GetProvider() { return null; }
    public object GetScope() { return null; }
    public object Resolve() { return null; }
}

そしてそれを使用するよりも

kernel.Bind<IDataSender>()
      .To<RemotingDataSender>()
      .When( a => a.Parameters
                   .Single( b => b.Name == "connection" )
                   .GetValue( new DummyContext(), a.Target ) 
               as RemotingConnection != null );

誰かが Context を内部から取得することについての情報を投稿できればいいのですがWhen()...

于 2013-03-07T12:03:44.293 に答える