Search code examples
c#restasp.net-web-apiservicemicroservices

Separation of Services issue causing problems


I have a project with the following structure:

Main Rest

Main Services

Second Rest

Second Services

Third Rest

Third Services

Fourth....

Data Layer

etc

In terms of dependency, all Rest layers can access the Main Services and their own Service eg Second Rest can access Second and Main Services but not Third, and so on.

The issue I am facing now is that increasingly Second Services needs to access parts of the code in Third Services and so on.

The temptation is to move that code from Second Services to Main Services-but this does not seem right to me and is making me question if this separation and if it is useful.

I also dont think it is quite right to move all the code in one big Service and have everything access it from there.

One thing I did think of was an Inter Project Service layer that can provide the link between the Service Layers, but realistically I would need one of these for each of the Services to avoid circular references.

Finally, to complicate matters further I have to thing about Dependency Injection and the different implementations of interfaces between projects.

Has anyone experienced this kind of issue with a good solution?

Refactoring the whole project is not an option as I have to consider business needs and it does not make sense to do this financially.


Solution

  • I had experience refactoring big pile of mud, where everything was entangled. One thing that I've found most helpful was to invert dependencies for functions / methods too. If Rest2 calls Service2.Foo which wants data from Service1, the it's Rest2's job to bring the data.

    To further enforce this approach, combat temptation to write and use various utility and convenience functions, that do cross-service calls for you, or at least keep these function private for each module.

    This somewhat aligns with idea of CQS, extrapolated even further: each function is either doing some job independently or orchestrates whole team (as big as needed) of workers.

    The noticeable downside of this approach is increased size of "flattened" top-level functions, but in my case it was much smaller problem than entanglement.

    Ideally, this approach should yield set of modules organized in hierarchy of layers, where no module is allowed to call it's siblings or higher layers. Non-cyclic data flows are much easier to reason about!