Ninject条件结合基于参数类型 [英] Ninject conditional binding based on parameter type
问题描述
我使用一个工厂返回一个datasender:
绑定< IDataSenderFactory>()
.ToFactory();公共接口IDataSenderFactory
{
IDataSender CreateDataSender(连接接口);
}
我有datasender的两种不同的实现(WCF和远程),它采取不同的类型:
公共抽象类连接
{
公共字符串服务器名{获得;组; }
}公共类WcfConnection:连接
{
// specificProperties等。
}公共类RemotingConnection:连接
{
// specificProperties等。
}
我想使用Ninject绑定基于从参数传递的连接类型,这些特定类型datasender的。我曾尝试以下失败:
绑定< IDataSender>()
。要< RemotingDataSender>()
。当(A => a.Parameters.Single(B = GT; b.Name ==连接)作为RemotingConnection!= NULL)
我相信这是因为'。当'只是提供了一个请求,我需要完整的上下文能够检索实际的参数值,并检查它的类型。我在茫然,做什么,比使用命名绑定,实际执行的工厂,把逻辑在里面即其他。
公共IDataSender CreateDataSender(连接连接)
{
如果(connection.GetType()== typeof运算(WcfConnection))
{
返回resolutionRoot.Get< IDataSender>(wcfdatasender,新ConstructorArgument(连接连接));
} 返回resolutionRoot.Get< IDataSender>(remotingdatasender,新ConstructorArgument(连接连接));
}
经过一番寻找到Ninject源,我发现以下内容:
-
a.Parameters.Single(B => b.Name ==连接)
为您提供了变量类型的IParameter
,不是真正的参数。 -
IParameter
的方法对象的GetValue(IContext背景下,ITarget目标)
,要求不为空上下文参数(目标可以为null)。 -
我还没有发现任何方式(样品中的变量a)由请求获得IContext。
-
上下文
类没有参数的构造函数,所以我们不能创建新的上下文。
要使它工作,你可以创建虚拟IContext实现这样的:
公共类DummyContext:IContext
{
公众的iKernel内核{搞定;私人集; }
公共IRequest请求{搞定;私人集; }
公共IBinding绑定{搞定;私人集; }
公共IPLAN计划{搞定;组; }
公众的ICollection< IParameter>参数{搞定;私人集; }
公共类型[] {GenericArguments获得;私人集; }
公共BOOL HasInferredGenericArguments {搞定;私人集; }
公共IProvider GetProvider(){返回NULL; }
公共对象GetScope(){返回NULL; }
公共对象解决(){返回null; }
}
和超过使用它
kernel.Bind< IDataSender>()
。要< RemotingDataSender>()
。当(一个= GT; a.Parameters
。单(B = GT; b.Name ==连接)
.GetValue(新DummyContext(),a.Target)
作为RemotingConnection = NULL)!;
这将是很好,如果有人可以张贴有关从获取上下文中一些信息。当()
...
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:
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. 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 i.e.
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:
a.Parameters.Single(b => b.Name == "connection")
gives you variable of typeIParameter
, not real parameter.IParameter
has methodobject GetValue(IContext context, ITarget target)
that requires not null context parameter (target can be null).I have not found any way to get IContext from Request (variable a in your sample).
Context
class does not have parameterless constructor so we can't create new Context.
To make it work you can create dummy IContext implementation like:
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()
...
这篇关于Ninject条件结合基于参数类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!