Skip to content

SonnevilleJ/CSharp-Dependency-Injection-Kata

Repository files navigation

Dependency Injection Kata

A small code kata to practice dependency injection in C# using Ninject.

Goals

  1. Implement an IoC container using Ninject
  2. Inject all dependencies throughout the application
  3. Improve testability throughout the application

Exercises

In this kata, you will perform several refactorings to achieve the goals stated above. I will guide you through the following steps:

  1. Refactor Generator class to inject dependency - Changeset
  2. Configure a Ninject kernel with appropriate bindings - Changeset
  3. Move bindings into a Ninject Module - Changeset
  4. Extract App from Program - Changeset
  5. Refactor tests to mock injected dependencies - Changeset
  6. Test drive the addition of a dependency binding - Changeset

Steps 4 and later are not required for dependency injection, but are merely benefits of it. Step 4 allows all dependencies (including the Ninject kernel bindings) to be tested. Without this step, integration tests remain quite possible, although mocking dependencies is nearly impossible when calling Main() from a test.

Additional Considerations

Once you've completed all exercises, I'll leave you to ponder a few other considerations:

  • For new applications, when is the right time to introduce dependency injection? What about an IoC container?
  • How should bindings be organized within a large application?
  • How do you balance application config with bindings? Do you read config values before processing bindings, or should your types read config values themselves?
  • Should libraries contain bindings for their types, or should bindings live in an executable?
  • Should the full dependency graph be constructed immediately at runtime, or should some dependencies be constructed on demand when the user enters a certain section of the application?
    • How might such lazy instantiation be implemented?
    • What are the consequences of each option?
  • When should tests use the production kernel, a test-only kernel, or no kernel? Under what circumstances, if any, should you (re)bind dependencies to mocks?

Releases

No releases published

Packages

No packages published

Languages