I have global flags which enable/disable features. I'd like to inject some dependencies depending on some flag. Some features require classes which are heavily constructed so I want to inject null if the value of the flag is false and the actual dependency otherwise. Ninject doesn't allow injecting null. Are there any other options?
Update: constructor arguments can be decorated with OptionalAttribute
attribute. In this case null is injected if there is no corresponding binding found. There is a problem here: I can't verify if target class can be properly constructed. I have a test for each public dependency which verifies if it can be constructed successfully. In case if the value of the flag is true I will not be able to find the error when the dependency decorated with the OptionalAttribute
attribute, cannot be constructed properly. I'd like to manage it on binding level only.
Ninject is a lightweight dependency injection framework for . NET applications. It helps you split your application into a collection of loosely-coupled, highly-cohesive pieces, and then glue them back together in a flexible manner.
Ninject helps you use the technique of dependency injection to break your applications into loosely-coupled, highly-cohesive components, and then glue them back together in a flexible manner.
You can vary the injection behaviour by binding using a factory method (i.e. ToMethod
), and it's possible to allow injection of nulls by configuring the container's AllowNullInjection
setting.
Another alternative would be to use a factory method and supply a lightweight dummy object instead of your heavy-weight class. If you are using interfaces this would be straightforward, just have implementations of the interface that do nothing. You could even use a mocking framework such as FakeItEasy to construct these dummies for you. The benefit here, is that the dummy makes the special behaviour transparent to clients i.e. clients do not need to check for null
, etc.
An example of using a factory method, plus AllowNullInjection
and nulls:
public void Configure()
{
bool create = true;
IKernel kernel = new StandardKernel();
kernel.Settings.AllowNullInjection = true;
kernel.Bind<IFoo>().ToMethod(ctx => create ? ctx.Kernel.Get<Foo>() : null);
DependendsOnIFoo depFoo = kernel.Get<DependendsOnIFoo>();
}
private interface IFoo {}
private class Foo : IFoo {}
private class DependendsOnIFoo
{
public DependendsOnIFoo(IFoo foo) {}
}
And an example where a lightweight object is substituted depending on the flag:
public void Configure()
{
bool heavy = true;
IKernel kernel = new StandardKernel();
kernel.Bind<IFoo>()
.ToMethod(ctx => heavy ? ctx.Kernel.Get<HeavyFoo>() : (IFoo)new DummyFoo());
DependendsOnIFoo depFoo = kernel.Get<DependendsOnIFoo>();
}
private interface IFoo {}
private class HeavyFoo : IFoo {}
private class DummyFoo : IFoo { }
private class DependendsOnIFoo
{
public DependendsOnIFoo(IFoo foo) {}
}
Injecting null is usually not a wise idea. This will pollute your code with checks if the object is null or not as shown by the following code:
public interface IFoo
{
void Do();
}
public class Foo : IFoo
{
public void Do()
{
DoSomething();
}
}
public class UglyNullCheckingBar
{
IFoo foo;
public Bar(IFoo foo)
{
this.foo = foo;
}
public void Do()
{
if (this.foo != null)
{
this.foo.Do();
}
}
}
The better way in this case is to implement a Null Object which does absolutely nothing and inject this one instead of null. This keeps your code clean.
public class NullFoo : IFoo
{
public void Do() {}
}
public class Bar
{
IFoo foo;
public Bar(IFoo foo)
{
this.foo = foo;
}
public void Do()
{
this.foo.Do();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With