【问题标题】:Ninject conditional binding based on parameter typeNinject 基于参数类型的条件绑定
【发布时间】:2013-02-22 10:13:05
【问题描述】:

我正在使用工厂返回数据发送器:

Bind<IDataSenderFactory>()
    .ToFactory();

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

我有两种不同的数据发送器实现(WCF 和远程处理),它们采用不同的类型:

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

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

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

我正在尝试使用 Ninject 根据从参数传递的 Connection 类型来绑定这些特定类型的数据发送器。我尝试了以下失败:

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

【问题讨论】:

    标签: c# binding ninject conditional


    【解决方案1】:

    在研究了 Ninject 源代码后,我发现了以下内容:

    • a.Parameters.Single(b =&gt; b.Name == "connection") 为您提供IParameter 类型的变量,而不是实际参数。

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

    • 我还没有找到从 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 );
    

    如果有人能发布一些关于从When()内部获取上下文的信息,那就太好了...

    【讨论】:

    • 我支持从 When(...) 过滤器中获取 IContext 的信息请求,但我会试一试虚拟上下文
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 2019-02-18
    • 1970-01-01
    相关资源
    最近更新 更多