Ninject条件结合基于参数类型(Ninject conditional binding base

2019-08-17 08:32发布

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

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绑定基于从参数传递的连接的类型,这些特定类型datasender的。 我曾尝试以下失败:

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

Answer 1:

一些寻找到Ninject源后,我发现以下几点:

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

  • IParameter具有方法object GetValue(IContext context, ITarget target) ,需要不空的上下文参数(目标可以为空)。

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

  • 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() ...



文章来源: Ninject conditional binding based on parameter type