0

I've implemented two services. One that pulls data from a Country API and another that pulls data from a County API.

I like to keep my controllers clean, so I'm curious if it's a good idea to combine my services together instead of keeping them apart.

I'm not exactly sure what constitutes tight coupling and when it's appropriate or not.

Should I go down this route:

public async Task<IActionResult> Get(
        [FromQuery] double latitude, 
        [FromQuery] double longitude
    {
        var countryService = new CountryService();
        var countryData = await countryService.Get(latitude, longitude);

        var countyService = new CountyService();
        var countyData = await countyService.Get(latitude, longitude);

        return Ok(new Data(countryData, countyData);
    }

OR

public async Task<IActionResult> Get(
        [FromQuery] double latitude, 
        [FromQuery] double longitude
    {
        var combinedService = new CombinedService();
        Data combinedData = await combinedService.Get(latitude, longitude);

        return Ok(combinedData);
    }
  • The amount of coupling is up to you. Might any consuming code ever need to get country data from one service and county data from another? Then perhaps they should be broken up into separate dependencies. If that's not the case, it may be just fine to simplify things and couple them. – mason Nov 08 '16 at 18:20
  • You define your own coupling. Can you use one service without the need of the other? If there are no performance/scalability reasons to combine the two services then I would define two separate services. – Ross Bush Nov 08 '16 at 18:22
  • You should make everything static. That'll couple up stuff good. –  Nov 08 '16 at 18:31
  • I will sometimes need to use the Country and County services separately. So instead, would it make sense to add the following public methods to CombinedService: GetBoth(lat, long), GetCountry(lat, long) and GetCounty(lat long)? The biggest reason I want to couple my code is to keep my controller clean. – HelloWorld1010 Nov 08 '16 at 18:32
  • 1
    In both sample cases the controller is tightly coupled to it's collaborators because the controller hard-codes it's dependencies rather than having them injected. You can achieve loose coupling even if the two services aren't combined, they just need to implement an interface on which the controller will depend rather than depending on the concrete implementation. – plalx Nov 08 '16 at 18:44
  • In your example, the coupling always is somewhere. Either in the controller or in CombinedService. I don't see a meaningful difference between the two. The same code just moved somewhere else. What differences to you see? – usr Nov 08 '16 at 19:45
  • @HelloWorld1010 - All of the code shown is tightly coupled. You need to clarify what you mean. – Enigmativity Nov 09 '16 at 00:03
  • I suggest you [watch this video](https://channel9.msdn.com/Events/TechEd/NorthAmerica/2014/DEV-B412#fbid=) as it explains much better about writing decoupled code and using dependency injection. This video greatly improved my code quality earlier in my career. – mason Nov 09 '16 at 14:32

2 Answers2

0

Tight coupling is an excellent idea when you sense cohesion on the domain level. In Eric Evans' book DDD the term Bounded Context is defined. Think about it this way: how much information/knowledge is shared between the two parts? If it's a relevantly high percentage you may as well couple them because they are already on the domain level. This also is affine to Larmans' GRASP definition of Information Expert.

More about this here.

pid
  • 11,472
  • 6
  • 34
  • 63
0

First, make sure that you're talking about tight coupling between CountryService and CountyService, not a tight coupling between your controller and services.

The example you gave has tightly coupled services and controller, which is never a good thing. A clean controller would accept a service interface in its constructor, not do a new on a concrete implementation.

As to whether or not to combine CountryService and CountyService into a CombinedService, the decision is simple:

  • keep them separate if you have at least one client that uses only one of them, and not the other
  • press them together is all clients use them in combination
user270576
  • 987
  • 10
  • 16