❔ Services becoming dependent on each-other, possible solution, opinions?
I'm pretty sure that asking for opinions is fine, at least I hope. (I think that software engineering isn't exact science, everything depends and has many approaches)
As I spoke to one kind user from here the other day, we talked about how services become dependent on each other as projects grow, which leads to many problem such as circular dependencies and another one which is fat constructor (large amounts of injections => many parameters => ugly code?).
Well, I tried solving this to come prepared and I started actually stumbling upon these problems in my project. (Which is just a simple Web Api I'm building for my Github profile). After reading Martin Fowler's book "Patterns of Enterprise Application Architecture", "Design Patterns Elements of Reusable Object-Oriented", Refactoring Guru and many SO issues, didn't come with many solutions apart from dumping services and migrate to CQRS(which the same kind senior talked to me about), Service Locator pattern, Property injection, and some more.
All seemed a bit weird to me, I can't explain, each had their drawbacks which I wasn't fancy about dealing with (except for CQRS which I wanted to use in another project and keep this one with services), so I came up with what you're seeing in this picture. I'm not sure if what I've done is a mix of some, maybe it's improper way to implement Service Locator, so I named it differently to not look like an idiot.
I'll try to explain what I'm doing:
1. A Gatherer would centralize calls between services by supplying the services.
2. Each controller is injected with the gatherer, then keeps only the relevant service as a prop.
3. When a Gatherer is instantiated, it is injected with all of the services (I don't like it but there had to be compromises).
4. To minimize code repetition I created
IAppService
and AppService
, which expose the AddGatherer(IServiceGatherer)
and implement it. (forgot to add impl rel in uml)
That's it, would appreciate other solutions and opinions.7 Replies
Thanks to anyone who helps! didn't have more characters left to say noticed that the relationship between the
I#Service
and IAppService
are pointing the wrong waythe idea of a gatherer that just wraps up a bunch of somewhat-related services to minimize repetition in constructor injection doesn't sound TOO crazy...
but I have trouble believing I would ever endorse it
if your constructors are so bloated with dependencies that that it's becoming cumbersome to write them out, I'm gonna call that a code smell, that indicates you need to factor some things apart
how many dependencies are we talking?
anything less than, say, 8, and I'm just gonna say "you're overthinking a non-problem"
and I'm gonna say the same thing for circular dependencies: it's a smell that indicates you don't have your separation of concerns right, and you probably can, and should, refactor to eliminate the circularity completely
would need to understand your specific scenario to dicuss any further
the question is too generic, we should enter into the details
the complexity of the solution depends on the size of the problem
you don't apply microservices to an architecture that gets 1 req/min and has a 1 MB database and viceversa you can't possibly have an architecture for 10k req/sec without thinking about redundancy, caching, backup, and so on
I see, would you consider that sharing the services themselves is a good practice? Sometimes in order to add a post you need the blog instance in-order to add the reference to it.
I can send you the repository privately if you want to look at the exact code I'm talking about
Well I though so but each service is only concerned with one entity/ model, it's when it comes to their relations with other entities that I need an access.
Well it's can be used I wouldn't use it myself, I'm building it for the sake of showcasing. I can send you the repo privately if you want to examine it and tell me your opinion/ suggetion
A) retrieving an entire blog just to add a new post to the database also sounds smelly
B) that sounds like a data access concern, not a business concern, I.E. the shared entity that does that blog retrieval should be coming from a lower layer, not a sibling layer
again, take all of my thoughts with a grain of salt, cause I'm not intimate with your codebase
can't you just share the repo here instead of sending it privately to everyone?
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.