2
votes

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 :)

1
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!pedrommuller
Then you should consider Unity of Microsoft: msdn.microsoft.com/en-us/library/ff647848.aspxThanh Nguyen
@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.Steven
@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!Thanh Nguyen
@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!AesopWaits

1 Answers

5
votes

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.