0

At the moment, the application I work on relies on an ISettingsService which is injected via the constructor; classic dependency injection. As time goes and the application's capabilities (understand complexities) build-up, the quantity and diversity of the settings exposed by the service have grown.

Some classes require ISettingsService to access just one out of dozens of settings, and it feels wrong. In order to resolve this, I am considering to create sub entities which would map subsets of settings, for example IDisplaySettingsService, which would map to the relevant properties of ISettingsService.

What are the reasons I should or should not do this? On one hand it seems that the dependency is more targeted, but it also feels that the mapper is just hiding a greater dependency: IDisplaySettingsService requires ISettingsService to be injected. So, am I truly solving a problem here?

My situation is similar to this post, but the angle of the question and the answers are slightly different.

1 Answer 1

1

What are the reasons I should or should not do this? On one hand it seems that the dependency is more targeted, but it also feels that the mapper is just hiding a greater dependency

The primary reason for splitting an interface like that is because it makes things easier for you and your team in a concrete, tangible way.

On the one hand, the more targeted dependency could mean it becomes easier to write tests, because there is less set-up code to write to wire up the part you want to test.

On the other hand, if you now get components that depend on both IDisplaySettingsService and IFooSettingService and IBarSettingService then you may have gone overboard and made it harder to maintain the code.

I am considering to create sub entities which would map subsets of settings, for example IDisplaySettingsService, which would map to the relevant properties of ISettingsService.

An actual mapper class is probably adding a bit too much complexity for retrieving settings. What might work better is a structure like this

interface IDisplaySettingsService {
  // Methods for accessing display-related settings
}

interface IFooSettingsService {
  // Methods for accessing foo-related settings
}

interface IBarSettingsService {
  // Methods for accessing bar-related settings
}

interface ISettingsService extends IDisplaySettingsService, IFooSettingsService, IBarSettingsService {
}

This way, each component can either declare a narrow dependency (on IFooSettingsService for example) or a broad dependency (on ISettingsService) and all those dependencies can be resolved with a single implementation of ISettingsService.

2
  • Thanks! I am a .Net person. By extending, are you suggesting that ISettingsService "inherits" the sub-services, so that there in fact is no additional implementation (mapping), but rather just a filtering mechanism through interfaces?
    – Ama
    Sep 15, 2021 at 9:52
  • 1
    @Ama, yes, that is the idea I wanted to express. Sep 15, 2021 at 9:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.