简体   繁体   English

Ninject基于参数类型的条件绑定

[英]Ninject conditional binding based on parameter type

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: 我有两种不同的数据集实现(WCF和远程处理),它们采用不同的类型:

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. 我试图使用Ninject根据从参数传递的Connection类型绑定这些特定类型的数据库。 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 ie 我不知道该做什么,除了使用命名绑定,实际上实现工厂并将逻辑放在那里,即

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: 在查看Ninject源代码后,我发现以下内容:

  • a.Parameters.Single(b => b.Name == "connection") gives you variable of type IParameter , not real parameter. a.Parameters.Single(b => b.Name == "connection")为您提供IParameter类型的IParameter ,而不是真实参数。

  • IParameter has method object GetValue(IContext context, ITarget target) that requires not null context parameter (target can be null). IParameter具有方法object GetValue(IContext context, ITarget target) ,它不需要null上下文参数(target可以为null)。

  • I have not found any way to get IContext from Request (variable a in your sample). 我还没有找到任何方法从Request获取IContext(样本中的变量a)。

  • Context class does not have parameterless constructor so we can't create new Context. Context类没有无参数构造函数,因此我们无法创建新的Context。

To make it work you can create dummy IContext implementation like: 为了使它工作,您可以创建虚拟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; }
}

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() ... 如果有人可以发布一些关于从When()内部获取Context的信息会很好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM