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