I have been working with Ninject to implement an application using dependency injection. I feel like I have a pretty thorough understanding of the concepts and have really liked the loosely coupled and testable architecture that the application has achieved using DI. I am struggling with one specific type of service, however, and am looking for insight into whether I am doing something wrong or if others have ran across the same thing.
Basically, I end up with some services/classes (a pretty small number) that have no other services depending on them. Because of this, the class never gets instantiated even though it is required to since it performs a useful role in the application. As an example, say I have an IMonkeyRepository
service and an IMonkeyPopulator
service. Assume the IMonkeyPopulator
service really has no public API, and its sole responsibility (following the Single Responsibility Principle) is to discover monkeys on the network and populate the IMonkeyRepository
with them. This service depends on the IMonkeyRepository
and perhaps some other service(s) to handle its interaction with the network (configuration data for ports and addresses, for example). However, the IMonkeyPopulator
has no public API, its just an empty interface.
Is this a bad design or some sort of code smell that I'm missing? I could obviously move this functionality into the repository itself but that seems like a violation of SRP to me (the repository has useful access functions, etc., and could actually be populated by multiple services). Some approaches that I've considered or tried but am not happy with are:
Any thoughts or guidance?
You say that the IMonkeyPopulator
depends on the IMonkeyRepository
, but it seems like that should be the other way around? It sounds like your IMonkeyRepository
depends on, and consequently may need to be injected with, an IMonkeyPopulator
. If you also inject some other service fine, but internally, the IMonkeyRepository
could tell the IMonkeyPopulator
to "start" so that there's actually something in the repository? I might be misunderstanding the problem though... maybe I shouldn't be monkeying around so much :/
Your IMonkeyPopulator
is therefore some kind of ActiveObject
which listens on a tcp connection in the background and writes that data into the repository. I would say from an application perspective that active object has to be started and stopped because you don't want to start the tcp connection in the constructor. So you can use the OnActivation
and OnDeactivation
methods on the binding to start and stop the service like so:
This.Bind<IPopulatorService>().To<>().OnActivation((c, i) => i.Start()).OnDeactivation((c, i) => i.Stop())
But still someone in your application has to fetch/get the IPopulatorService
in order to get it instantiated in your application. I usually use the bootstrapper pattern here http://www.appccelerate.com/bootstrapper.html in order to achive this.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.