Nat*_*lor 8 c# binding conditional ninject
我正在使用工厂返回数据库:
Bind<IDataSenderFactory>()
.ToFactory();
public interface IDataSenderFactory
{
IDataSender CreateDataSender(Connection connection);
}
Run Code Online (Sandbox Code Playgroud)
我有两种不同的数据集实现(WCF和远程处理),它们采用不同的类型:
public abstract class Connection
{
public string ServerName { get; set; }
}
public class WcfConnection : Connection
{
// specificProperties etc.
}
public class RemotingConnection : Connection
{
// specificProperties etc.
}
Run Code Online (Sandbox Code Playgroud)
我试图使用Ninject根据从参数传递的Connection类型绑定这些特定类型的数据库.我尝试了下面的失败:
Bind<IDataSender>()
.To<RemotingDataSender>()
.When(a => a.Parameters.Single(b => b.Name == "connection") as RemotingConnection != null)
Run Code Online (Sandbox Code Playgroud)
我相信这是因为'.'只提供一个请求,我需要完整的上下文才能检索实际参数值并检查其类型.我不知道该做什么,除了使用命名绑定,实际上实现工厂并将逻辑放在那里,即
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));
}
Run Code Online (Sandbox Code Playgroud)
在查看Ninject源代码后,我发现以下内容:
a.Parameters.Single(b => b.Name == "connection")给你变量的类型IParameter,而不是真实的参数.
IParameter具有object GetValue(IContext context, ITarget target)不需要null上下文参数的方法(target可以为null).
我还没有找到任何方法从Request获取IContext(样本中的变量a).
Context class没有无参数构造函数,因此我们无法创建新的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; }
}
Run Code Online (Sandbox Code Playgroud)
而不是使用它
kernel.Bind<IDataSender>()
.To<RemotingDataSender>()
.When( a => a.Parameters
.Single( b => b.Name == "connection" )
.GetValue( new DummyContext(), a.Target )
as RemotingConnection != null );
Run Code Online (Sandbox Code Playgroud)
如果有人可以发布一些关于从内部获取Context的信息,这将是很好的When()...