Ninject条件基于参数类型的结合

问题描述:

我使用工厂来返回一个datasender:Ninject条件基于参数类型的结合

Bind<IDataSenderFactory>() 
    .ToFactory(); 

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

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

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

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

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

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

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

我相信这是因为“当”只是提供了一个请求,我就需要完整的上下文能够检索的实际参数值,并检查它的类型。我手足无措,不知道该做什么,比使用命名绑定,实际执行的工厂,把逻辑在里面,即

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

经过一番寻找到Ninject源,我发现下面的其他:

  • a.Parameters.Single(b => b.Name == "connection")给你变量的类型IParameter,而不是真正的参数。

  • IParameter有方法object GetValue(IContext context, ITarget target),它要求非空上下文参数(目标可以为空)。

  • 我还没有找到任何方法从请求中获取IContext(样本中的变量a)。

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

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