Ninject dependency injection: Read bindings from config?
Asked Answered
P

1

2

I'm new to automatic dependency injection and trying to cleanly implement Ninject with an MVC4 application. Everything is functional but the OCD in me is wondering how an application will scale in terms of listing bindings in the RegisterServices(IKernel kernel) method in NinjectWebCommon.cs. For example,

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IAbstractManagerA>().To<ConcreteManagerA>();
        kernel.Bind<IAbstractManagerB>().To<ConcreteManagerB>();
        kernel.Bind<IAbstractRepoA>().To<ConcreteRepoA>();
        ...etc etc could be hundreds
    }    

Is there a better way to handle this? Maybe have each pairing as a web.config setting or some other config file? Essentially inject the dependencies for the dependency injection :)

Plectron answered 13/8, 2013 at 21:30 Comment(7)
have you consider to use a convention over configuration? Ninject and Structuremap provides the scanner function for such configurations like scanner.FromCallingAssembly(); scanner.BindWithDefaultConventions(); in my personal opinion mixing a xml file configuration and IoC doesn't mix well, that's the reason why that functionality is deprecated in structuremap, hope that helps!Scold
Then you should consider Unity of Microsoft: msdn.microsoft.com/en-us/library/ff647848.aspxBliss
@ThanhNguyen: Seriously, you can't just advice Unity. There's little that Unity can do, what the other frameworks (such as Ninject) can't do.Pernambuco
@Steven: He wants to read bindings from config and I just think Unity is quite good at that stuff.Bliss
@ThanhNguyen: I agree, the XML support of Unity is nice since it allows you to alias type names, but for the rest, other containers allow you to do the same with XML. But the thing is... using an XML configuration file as primary source for DI configuration is brittle, error prone and a maintenance hell. XML should only be used for that few dependencies that really need to be changed after deployment, and even then, it's often much better to implement configuration switches (like <add name="Production" value="true" />) and leave type names completely out of the XML.Pernambuco
@Steven: I can't agree more Steven :) I just tried to focus on his specific need not on system designing aspects, anyway, you're totally right!Bliss
@Pedro your idea is intriguing. Wasn't aware Ninject had such a feature. Using reflection and naming conventions may eliminate the need for endless hard coded bindings as well as an external configuration file. I'll look into this further. Thanks!Plectron
P
5

Consider designing your applications around a few well defined generic abstractions, such as:

  • IRepository<TEntity> to hide database CRUD operations behind
  • ICommandHandler<TCommand> to define your systems business operation / use cases (example).
  • IQueryHandler<TQuery, TResult> to define custom queries that can be used by business logic (example).
  • IValidator<T> as an abstraction over classes that can validate entities or commands (example).

Applying this type of design as a few clear benefits:

  1. It forces you into a clean and SOLID application design.
  2. It makes it easy to add cross-cutting concerns around all implementations of a certain concept (for instance a decorator that adds a transaction around each business operation).
  3. It makes it easy to batch register a whole range of related types.
  4. It makes it much easier to build maintainable solutions on top of this, such as maintenance free WCF services.
Pernambuco answered 14/8, 2013 at 7:7 Comment(1)
I've been following your blog and answers on SO with great interest. And this answer sums up all of the goodies, with examples included. Couldn't ask for more. Many thanks!Jampack

© 2022 - 2024 — McMap. All rights reserved.