I have a solution which has the following projects:
- Core (contains classes for processing, not related to business objects / domain)
- Domain (contains business objects)
- Harness (console app)
- MVC4 app
- Persistence (contains implementations of repository interfaces, EF mappings, etc)
- Repositories (contains repository interface)
- Tests (contains unit tests)
I would like to use NInject as my IoC container as I have experience with it however I am open to suggestions for something that would better suit my needs.
The domain objects need to know about the repository so they can do data access (i.e. the Person class might want to retrieve all AddressDetails). Everything is coded to interfaces to help with mocks in unit testing.
I don’t want the domain project taking on a dependence on an IoC container but I need some way of having all instances created in the domain project getting the right repositories injected. How can I do this? I also want to be able to do injections from the harness and test project where necessary. The only way I can think of doing this is by having a static object in the Domain class which wraps the StandardKernel from NInject and call that to populate the dependencies. It would be nice also if i can have constructor injection working which I don’t think it would using that method. The other alternative I can think of is have a factory which builds the domain objects with the correct dependencies, but I’d rather be able to have IPerson person = new Person() rather than have to call a factory each time.
Thanks in advance.
Sounds like you should introduce Composition Root into MVC4 project and console application. Thus all dependencies will be coupled only there for whole production code. Also you may define your own implementation of
StandardKernel, or use autodiscovery to find all implementations.There is two examples how to implement
composition rootwith overload ofStandartKerneland autodiscovery atninject.web.mvcthat could be useful as starting point.Composition rootfor console application usually has trivial implementation.For test project you could use
ninject.mockingkernelwith appopriate mocking library, or build all dependencies yourself. Second option should be obvious for pure unittesting, but for integration tests first one is more appopriate.Injection of domain objects
First there are several well know injection method:
For example, implement only one not default constructor for domain object, that defines all required dependencies for that object. If it depends on repository, specify this in constuctor of domain object, and there is no other way to create this particular domain object without specifing it.