Ninject条件结合基于参数类型 [英] Ninject conditional binding based on parameter type

查看:180
本文介绍了Ninject条件结合基于参数类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用一个工厂返回一个datasender:

 绑定< IDataSenderFactory>()
    .ToFactory();公共接口IDataSenderFactory
{
    IDataSender CreateDataSender(连接接口);
}

我有datasender的两种不同的实现(WCF和远程),它采取不同的类型:

 公共抽象类连接
{
    公共字符串服务器名{获得;组; }
}公共类WcfConnection:连接
{
    // specificProperties等。
}公共类RemotingConnection:连接
{
    // specificProperties等。
}

我想使用Ninject绑定基于从参数传递的连接类型,这些特定类型datasender的。我曾尝试以下失败:

 绑定< IDataSender>()
    。要< RemotingDataSender>()
    。当(A => a.Parameters.Single(B = GT; b.Name ==连接)作为RemotingConnection!= NULL)

我相信这是因为'。当'只是提供了一个请求,我需要完整的上下文能够检索实际的参数值,并检查它的类型。我在茫然,做什么,比使用命名绑定,实际执行的工厂,把逻辑在里面即其他。

 公共IDataSender CreateDataSender(连接连接)
{
    如果(connection.GetType()== typeof运算(WcfConnection))
    {
        返回resolutionRoot.Get< IDataSender>(wcfdatasender,新ConstructorArgument(连接连接));
    }    返回resolutionRoot.Get< IDataSender>(remotingdatasender,新ConstructorArgument(连接连接));
}


解决方案

经过一番寻找到Ninject源,我发现以下内容:


  • a.Parameters.Single(B => b.Name ==连接)为您提供了变量类型的 IParameter ,不是真正的参数。


  • IParameter 的方法对象的GetValue(IContext背景下,ITarget目标),要求不为空上下文参数(目标可以为null)。


  • 我还没有发现任何方式(样品中的变量a)由请求获得IContext。


  • 上下文类没有参数的构造函数,所以我们不能创建新的上下文。


要使它工作,你可以创建虚拟IContext实现这样的:

 公共类DummyContext:IContext
{
    公众的iKernel内核{搞定;私人集; }
    公共IRequest请求{搞定;私人集; }
    公共IBinding绑定{搞定;私人集; }
    公共IPLAN计划{搞定;组; }
    公众的ICollection< IParameter>参数{搞定;私人集; }
    公共类型[] {GenericArguments获得;私人集; }
    公共BOOL HasInferredGenericArguments {搞定;私人集; }
    公共IProvider GetProvider(){返回NULL; }
    公共对象GetScope(){返回NULL; }
    公共对象解决(){返回null; }
}

和超过使用它

  kernel.Bind< IDataSender>()
      。要< RemotingDataSender>()
      。当(一个= GT; a.Parameters
                   。单(B = GT; b.Name ==连接)
                   .GetValue(新DummyContext(),a.Target)
               作为RemotingConnection = NULL)!;

这将是很好,如果有人可以张贴有关从获取上下文中一些信息。当() ...

I'm using a factory to return a datasender:

Bind<IDataSenderFactory>()
    .ToFactory();

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

I have two different implementations of datasender (WCF and remoting) which take different types:

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

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

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

I am trying to use Ninject to bind these specific types of datasender based on the type of Connection passed from the parameter. I have tried the following unsuccessfully:

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

I believe this is because '.When' only provides a request and I would need the full context to be able to retrieve the actual parameter value and check its type. I'm at a loss as to what to do, other than using named bindings, actually implementing the factory and putting the logic in there i.e.

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));
}

解决方案

After some looking into Ninject source I have found following:

  • a.Parameters.Single(b => b.Name == "connection") gives you variable of type IParameter, not real parameter.

  • IParameter has method object GetValue(IContext context, ITarget target) that requires not null context parameter (target can be null).

  • I have not found any way to get IContext from Request (variable a in your sample).

  • Context class does not have parameterless constructor so we can't create new Context.

To make it work you can create dummy IContext implementation like:

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; }
}

and than use it

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

It would be nice if someone could post some info about obtaining Context from inside When()...

这篇关于Ninject条件结合基于参数类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆