Using Ninject to bind an interface to multiple implementations unknown at compile time - ninject

I just recently started using Ninject (v2.2.0.0) in my ASP.NET MVC 3 application. So far I'm thrilled with it, but I ran into a situation I can't seem to figure out.
What I'd like to do is bind an interface to concrete implementations and have Ninject be able to inject the concrete implementation into a constructor using a factory (that will also be registered with Ninject). The problem is that I'd like my constructor to reference the concrete type, not the interface.
Here is an example:
public class SomeInterfaceFactory<T> where T: ISomeInterface, new()
{
public T CreateInstance()
{
// Activation and initialization logic here
}
}
public interface ISomeInterface
{
}
public class SomeImplementationA : ISomeInterface
{
public string PropertyA { get; set; }
}
public class SomeImplementationB : ISomeInterface
{
public string PropertyB { get; set; }
}
public class Foo
{
public Foo(SomeImplementationA implA)
{
Console.WriteLine(implA.PropertyA);
}
}
public class Bar
{
public Bar(SomeImplementationB implB)
{
Console.WriteLine(implB.PropertyB);
}
}
Elsewhere, I'd like to bind using just the interface:
kernel.Bind<Foo>().ToSelf();
kernel.Bind<Bar>().ToSelf();
kernel.Bind(typeof(SomeInterfaceFactory<>)).ToSelf();
kernel.Bind<ISomeInterface>().To ...something that will create and use the factory
Then, when requesting an instance of Foo from Ninject, it would see that one of the constructors parameters implements a bound interface, fetch the factory, and instantiate the correct concrete type (SomeImplementationA) and pass it to Foo's constructor.
The reason behind this is that I will have many implementations of ISomeInterface and I'd prefer to avoid having to bind each one individually. Some of these implementations may not be known at compile time.
I tried using:
kernel.Bind<ISomeInterface>().ToProvider<SomeProvider>();
The provider retrieves the factory based on the requested service type then calls its CreateInstance method, returning the concrete type:
public class SomeProvider : Provider<ISomeInterface>
{
protected override ISomeInterface CreateInstance(IContext context)
{
var factory = context.Kernel.Get(typeof(SomeInterfaceFactory<>)
.MakeGenericType(context.Request.Service));
var method = factory.GetType().GetMethod("CreateInstance");
return (ISomeInterface)method.Invoke();
}
}
However, my provider was never invoked.
I'm curious if Ninject can support this situation and, if so, how I might go about solving this problem.
I hope this is enough information to explain my situation. Please let me know if I should elaborate further.
Thank you!

It seems you have misunderstood how ninject works. In case you create Foo it sees that it requires a SomeImplementationA and will try to create an instance for it. So you need to define a binding for SomeImplementationA and not for ISomeInterface.
Also most likely your implementation breaks the Dependency Inversion Princple because you rely upon concrete instances instead of abstractions.
The solution to register all similar types at once (and the prefered way to configure IoC containers) is to use configuration by conventions. See the Ninject.Extensions.Conventions extenstion.

Related

Autofac Register closed types and retrieve them at run time

I have an Interface that will take in a generic type T
internal interface IQuestion<T> where T : IWithOptionsId
{
Task<T> Provide(Guid id);
}
Following by that I will implement this interface in multiple classes. For example
public class SomeProvider : IQuestion<OptionsClass>
{
private readonly IRepository _repository;
public SomeProvider(IRepository repository)
{
_repository = repository;
}
public async Task<OptionsClass> Provide(Guid id)
...
}
To register this with outofac I used this
Autofac.RegisterAssemblyTypes(
Assembly.GetExecutingAssembly())
.AsImplementedInterfaces()
.AsClosedTypesOf(typeof(IQuestion<>));
My question is this. I have multiple instances for this interface. How do I access different instance once at the run time? If my IQuestion<T> will take in Options class and also it will take in Answer class how can I get an instance of those classes during run time?
I'm pretty sure you can just inject the instance itself. Not great practice, but it should work:
public SomeClass(SomeProvider<OptionsClass> provider)
You could also try creating a named instance when you register it, and inject that. See this and this.

Do we need interfaces for dependency injection?

I have an ASP.NET Core application. The application has few helper classes that does some work. Each class has different signature method. I see lot of .net core examples online that create interface for each class and then register types with DI framework. For example
public interface IStorage
{
Task Download(string file);
}
public class Storage
{
public Task Download(string file)
{
}
}
public interface IOcr
{
Task Process();
}
public class Ocr:IOcr
{
public Task Process()
{
}
}
Basically for each interface there is only one class. Then i register these types with DI as
services.AddScoped<IStorage, Storage>();
services.AddScoped<IOcr,Ocr>();
But i can register type without having interfaces so interfaces here look redundant. eg
services.AddScoped<Storage>();
services.AddScoped<Ocr>();
So do i really need interfaces?
No, you don't need interfaces for dependency injection. But dependency injection is much more useful with them!
As you noticed, you can register concrete types with the service collection and ASP.NET Core will inject them into your classes without problems. The benefit you get by injecting them over simply creating instances with new Storage() is service lifetime management (transient vs. scoped vs. singleton).
That's useful, but only part of the power of using DI. As #DavidG pointed out, the big reason why interfaces are so often paired with DI is because of testing. Making your consumer classes depend on interfaces (abstractions) instead of other concrete classes makes them much easier to test.
For example, you could create a MockStorage that implements IStorage for use during testing, and your consumer class shouldn't be able to tell the difference. Or, you can use a mocking framework to easily create a mocked IStorage on the fly. Doing the same thing with concrete classes is much harder. Interfaces make it easy to replace implementations without changing the abstraction.
Does it work? Yes. Should you do it? No.
Dependency Injection is a tool for the principle of Dependency Inversion : https://en.wikipedia.org/wiki/Dependency_inversion_principle
Or as it's described in SOLID
one should “depend upon abstractions, [not] concretions."
You can just inject concrete classes all over the place and it will work. But it's not what DI was designed to achieve.
No, we don't need interfaces. In addition to injecting classes or interfaces you can also inject delegates. It's comparable to injecting an interface with one method.
Example:
public delegate int DoMathFunction(int value1, int value2);
public class DependsOnMathFunction
{
private readonly DoMathFunction _doMath;
public DependsOnAFunction(DoMathFunction doMath)
{
_doMath = doMath;
}
public int DoSomethingWithNumbers(int number1, int number2)
{
return _doMath(number1, number2);
}
}
You could do it without declaring a delegate, just injecting a Func<Something, Whatever> and that will also work. I'd lean toward the delegate because it's easier to set up DI. You might have two delegates with the same signature that serve unrelated purposes.
One benefit to this is that it steers the code toward interface segregation. Someone might be tempted to add a method to an interface (and its implementation) because it's already getting injected somewhere so it's convenient.
That means
The interface and implementation gain responsibility they possibly shouldn't have just because it's convenient for someone in the moment.
The class that depends on the interface can also grow in its responsibility but it's harder to identify because the number of its dependencies hasn't grown.
Other classes end up depending on the bloated, less-segregated interface.
I've seen cases where a single dependency eventually grows into what should really be two or three entirely separate classes, all because it was convenient to add to an existing interface and class instead of injecting something new. That in turn helped some classes on their way to becoming 2,500 lines long.
You can't prevent someone doing what they shouldn't. You can't stop someone from just making a class depend on 10 different delegates. But it can set a pattern that guides future growth in the right direction and provides some resistance to growing interfaces and classes out control.
(This doesn't mean don't use interfaces. It means that you have options.)
I won't try to cover what others have already mentioned, using interfaces with DI will often be the best option. But it's worth mentioning that using object inheritance at times may provide another useful option. So for example:
public class Storage
{
public virtual Task Download(string file)
{
}
}
public class DiskStorage: Storage
{
public override Task Download(string file)
{
}
}
and registering it like so:
services.AddScoped<Storage, DiskStorage>();
Without Interface
public class Benefits
{
public void BenefitForTeacher() { }
public void BenefitForStudent() { }
}
public class Teacher : Benefits
{
private readonly Benefits BT;
public Teacher(Benefits _BT)
{ BT = _BT; }
public void TeacherBenefit()
{
base.BenefitForTeacher();
base.BenefitForStudent();
}
}
public class Student : Benefits
{
private readonly Benefits BS;
public Student(Benefits _BS)
{ BS = _BS; }
public void StudentBenefit()
{
base.BenefitForTeacher();
base.BenefitForStudent();
}
}
here you can see benefits for Teachers is accessible in Student class and benefits for Student is accessible in Teacher class which is wrong.
Lets see how can we resolve this problem using interface
With Interface
public interface IBenefitForTeacher
{
void BenefitForTeacher();
}
public interface IBenefitForStudent
{
void BenefitForStudent();
}
public class Benefits : IBenefitForTeacher, IBenefitForStudent
{
public Benefits() { }
public void BenefitForTeacher() { }
public void BenefitForStudent() { }
}
public class Teacher : IBenefitForTeacher
{
private readonly IBenefitForTeacher BT;
public Teacher(IBenefitForTeacher _BT)
{ BT = _BT; }
public void BenefitForTeacher()
{
BT.BenefitForTeacher();
}
}
public class Student : IBenefitForStudent
{
private readonly IBenefitForStudent BS;
public Student(IBenefitForStudent _BS)
{ BS = _BS; }
public void BenefitForStudent()
{
BS.BenefitForStudent();
}
}
Here you can see there is no way to call Teacher benefits in Student class and Student benefits in Teacher class
So interface is used here as an abstraction layer.

Ninject NHibernate on plugin oriented architecture

According COMPOSITION ROOT pattern, I must to construct all dependencies graph as close as possible to the application's entry point.
My architecture is plugin oriented. So, if someone wants to extend my base system he can.
For example, in my base system I have this structure:
View Layer
Services Layer
Data Access Layer
Model Layer
In DAL, I expose some classes like:
IRepository
NHibernateRepository
ProductRepository
So, I'd like if a plugin wants to extend my base Product class to ExtendedProduct, and then create ExtendedProductRepository that inherits from NHibernateRepository.
The question is:
How can instantiate from my base system an instance of NHibernateRepository using NInject?
So, I know the first thing to do is to construct the graph dependencies:
using (var kernel = new StandardKernel())
{
kernel.Bind(b => b.FromAssembliesMatching("*")
.SelectAllClasses()
.InheritedFrom<IRepository>()
.BindAllInterfaces());
}
However, I'm figuring out that when I execute something like:
kernel.GetAll<IRepository>()
It's going to return me a ProductRepository instance, and another ProductExtendedRepository under two IRepository objects.
So, how I can save a ProductExtended object from my base system...?
Another question, would be, how could I inject a object instance in my plugins, or, how can plugins autoinject some instance of base system assembly?
Thanks for all.
I'll appreciate a lot some help.
I use this pattern for my NHibernate based projects:
public interface IRepository<T> : IQueryable<T>
{
T Get(int id);
void Save(T item);
void Delete(T item);
}
public class NHibernateRepository<ModelType> : IRepository<ModelType>
where ModelType : class
{
// implementation
}
then...
public interface IProductRepository : IRepository<Product>
{
// product specific data access methods
}
public class ProductRepository : NHibernateRepository<Product>, IProductRepository
{
// implementation
}
... and in Ninject Module:
Bind(typeof(IRepository<>)).To(typeof(NHibernateRepository<>));
Bind<IProductRepository>().To<ProductRepository>();
then you can either request the base functionality like:
public Constructor(IRepository<Product> repo) { ... }
or specific product repository functionality:
public Constructor(IProductRepository repo) { ... }
your plugins can either get the base functionality and won't have to register anything:
public PluginConstructor(IRepository<ProductExtended> repo { ... }
or create their own repositories and register them in a Ninject module.
Thanks dave.
It's perfect. I'll try it.
However, how could I save or get or update (whichever IRepository methods)... an ExtendedProduct instance from my base system?
Think the follow out:
public interface BasePlugin<T> {...}
In another assembly:
public class PluginExtendedProduct : BasePlugin<ExtendedProduct>
{
public PluginExtendedProduct (IRepository<ExtendedProduct> repo { ... }
}
My headache is how to create an instance of (so, ExtendedProduct) in my base system in order to call methods PluginExtendedProduct that uses an IRepository.
I don't know if I'm explaining myself well...
Thanks for all.

Avoid adding/extending methods to interface

I have a scenario , where my current interface looks like
public interface IMathematicalOperation
{
void AddInt();
}
After an year i expect the interface to be extended with AddFloat method and also expect 100 users already consuming this interface. When i extend the interface with a new method after an year i don't want these 100 classes to get changed.
So how can i tackle this situation ? Is there any design pattern available already to take care of this situation ?
Note: i understand that i can have a abstract class which implement this interface and make all the methods virtual , so that clients can inherit from this class rather than the interface and override the methods . When i add a new method only the abstract class will be changed and the clients who are interested in the method will override the behavior (minimize the change) .
Is there any other way of achieving the same result (like having a method named Add and based on certain condition it will do Float addition or Integer addition) ?
Edit 1:
The new method gets added to the interface also needs to be called automatically along with the existing methods(like chain of responsibility pattern).
There are at least two possible solution I can think of:
Derive your new interface from your old interface
public interface IMathematicalOperation
{
void AddInt();
}
public interface IFloatingPointMathematicalOperation : IMathematicalOperation
{
void AddFloat();
}
Have simply a parallel interface which contains the new method and have all classes which need the new interface derive from it
I'd suggest the second solution, since I don't understand why you would want an established interface to change.
I encountered a similar issue some time ago and found the best way was not to try and extend an existing interface, but to provide different versions of the interface with each new interface providing extra functionality. Over time I found that was not adding functionality on a regular basis, may once a year, so adding extra interfaces was never really an issue.
So, for example this is your first version of the interface:
public interface IMathematicalOperation
{
void AddInt();
}
This interface would then be implemented on a class like this:
public class MathematicalOperationImpl : IMathematicalOperation
{
public void AddInt()
{
}
}
Then when you need to add new functionality, i.e. create a version 2, you would create another interface with the same name, but with a "2" on the end:
public interface IMathematicalOperation2 : IMathematicalOperation
{
void AddFloat();
}
And the MathematicalOperationImpl would be extended to implement this new interface:
public class MathematicalOperationImpl : IMathematicalOperation, IMathematicalOperation2
{
public void AddInt()
{
}
public void AddFloat()
{
}
}
All of your new/future clients could start using the version 2 interface, but your existing clients would continue to work because they will only know about the first version of the interface.
The options provided are syntactically viable but then, as is obvious, they won't apply to any previous users.
A better option would be to use the Visitor pattern
The pattern is best understood when you think about the details of OO code
this.foo(); // is identical to
foo(this);
Remember that there is always a hidden 'this' parameter passed with every instance call.
What the visitor pattern attempts to do is generalize this behavior using Double dispatch
Let's take this a hair further
public interface MathematicalOperation
{
void addInt();
void accept(MathVisitor v);
}
public interface MathVisitor {
void visit(MathematicalOperation operation);
}
public class SquareVistor implements MathVisitor {
void visit(MathematicalOperation operation) {
operation.setValue(operation.getValue() * 2);
}
}
public abstract class AbstractMathematicalOperation implements MathematicalOperation {
public void accept(MathVisitor f) {
f.visit(this); // we are going to do 'f' on 'this'. Or think this.f();
}
}
public class MyMathOperation extends AbstractMathematicalOperation {
}
someMathOperation.visit(new SquareVisitor()); // is now functionally equivalent to
someMathOperation.square();
The best bet would be for you to roll-out your initial interface with a visitor requirements, then immediately roll-out an abstract subclass that gives this default implementation so it's cooked right in (As the above class is). Then everyone can just extend it. I think you will find this gives you the flexibility you need and leaves you will the ability to work with legacy classes.

Inheriting ConstructorArguments in Ninject

I'm trying to find a method of passing a constructor argument to the constructors of child classes.
These objects are immutable so I'd prefer to use constructor arguments.
The issue I have encountered is that ConstructorArgument does not inherit to child instantiations and the following statements are not interchangeable:
_parsingProcessor = _kernel.Get<IParsingProcessor>(new ConstructorArgument("dataFilePath", dataFilePath);
and
_parsingProcessor = _kernel.Get<IParsingProcessor>(new Parameter("dataFilePath", dataFilePath, true);
So, how can get an inheritable ConstructorArgument and when does it makes sense, if ever, to new the Parameter class?
Yes, you can do this, but it's probably not what you really want. If the container is not actually responsible for instantiating its own dependencies, then its dependencies probably shouldn't be sharing its constructor arguments - it just doesn't make sense.
I'm pretty sure I know what you're trying to do, and the recommended approach is to create a unique binding specifically for your one container, and use the WhenInjectedInto conditional binding syntax, as in the example below:
public class Hello : IHello
{
private readonly string name;
public Hello(string name)
{
this.name = name;
}
public void SayHello()
{
Console.WriteLine("Hello, {0}!", name);
}
}
This is the class that takes a constructor argument which we want to modify, depending on who is asking for an IHello. Let's say it's this boring container class:
public class MyApp : IApp
{
private readonly IHello hello;
public MyApp(IHello hello)
{
this.hello = hello;
}
public virtual void Run()
{
hello.SayHello();
Console.ReadLine();
}
}
Now, here's how you do up the bindings:
public class MainModule : NinjectModule
{
public override void Load()
{
Bind<IApp>().To<MyApp>();
Bind<IHello>().To<Hello>()
.WithConstructorArgument("name", "Jim");
Bind<IHello>().To<Hello>()
.WhenInjectedInto<MyApp>()
.WithConstructorArgument("name", "Bob");
}
}
Basically all this binding is doing is saying the name should be "Jim" unless it's being requested by Hello, which in this case it is, so instead it will get the name "Bob".
If you are absolutely certain that you truly want cascading behaviour and understand that this is very dangerous and brittle, you can cheat using a method binding. Assuming that we've now added a name argument to the MyApp class for some unspecified purpose, the binding would be:
Bind<IHello>().ToMethod(ctx =>
ctx.Kernel.Get<Hello>(ctx.Request.ParentContext.Parameters
.OfType<ConstructorArgument>()
.Where(c => c.Name == "name")
.First()));
Please, please, make sure you are positive that this is what you want before doing it. It looks easy but it is also very likely to break during a simple refactoring, and 95% of the "customized dependency" scenarios I've seen can be addressed using the WhenInjectedInto binding instead.