问题
When setting up my ninject bindings, I'm using the .ToMethod to specify particular parameters for specific connectionstrings, and the WhenInjectedInto method to constrain the binding to specific types:
Bind(Of IDbConnection).ToMethod(Function(context) New OracleConnection(ConnectionStringFactory.GetConnection(DBC.ConnectionStrings.Oracle))).WhenInjectedInto(Of AccountBalancesLookup)()
Bind(Of IDbConnection).ToMethod(Function(context) New OracleConnection(ConnectionStringFactory.GetConnection(DBC.ConnectionStrings.Oracle))).WhenInjectedInto(Of MFUtility)()
My question is, can I do something like this:
Bind(Of IDbConnection).ToMethod(Function(context) New OracleConnection(ConnectionStringFactory.GetConnection(DBC.ConnectionStrings.Oracle))).WhenInjectedInto(Of AccountBalancesLookup, MFUtility)()
Specifying more than one destination for the binding at once, rather than having multiple lines?
回答1:
Not out of the box. But you can create your own extension to When(Func<IRequest,bool>)
which does exactly that. For example:
public static class WhenExtensions
{
public static IBindingInNamedWithOrOnSyntax<T> WhenInjectedInto<T>(
this IBindingWhenSyntax<T> syntax, params Type[] types)
{
var conditions = ComputeMatchConditions(syntax, types).ToArray();
return syntax.When(request => conditions.Any(condition => condition(request)));
}
private static IEnumerable<Func<IRequest, bool>> ComputeMatchConditions<T>(
IBindingWhenSyntax<T> syntax, Type[] types)
{
foreach (Type type in types)
{
syntax.WhenInjectedInto(type);
yield return syntax.BindingConfiguration.Condition;
}
}
}
used like:
public class Test
{
[Fact]
public void Foo()
{
var kernel = new StandardKernel();
kernel.Bind<string>().ToConstant("Hello")
.WhenInjectedInto(typeof(SomeTypeA), typeof(SomeTypeB));
kernel.Bind<string>().ToConstant("Goodbye")
.WhenInjectedInto<SomeTypeC>();
kernel.Get<SomeTypeA>().S.Should().Be("Hello");
kernel.Get<SomeTypeB>().S.Should().Be("Hello");
kernel.Get<SomeTypeC>().S.Should().Be("Goodbye");
}
}
public abstract class SomeType
{
public string S { get; private set; }
protected SomeType(string s)
{
S = s;
}
}
public class SomeTypeA : SomeType
{
public SomeTypeA(string s) : base(s) { }
}
public class SomeTypeB : SomeType
{
public SomeTypeB(string s) : base(s) { }
}
public class SomeTypeC : SomeType
{
public SomeTypeC(string s) : base(s) { }
}
Note that ComputeMatchConditions
is kind of a hack because it relies on ninject internals.. if these (the implementation of WhenInjectedInto
) change then this may stop to work. Of course you're free to provide your own alternative implementation. You could also copy the code from WhenInjectedInto
, see: BindingConfigurationBuilder.cs method WhenInjectedInto(Type parent)
来源:https://stackoverflow.com/questions/30784103/can-i-specify-multiple-parameters-using-wheninjectedinto-for-ninject