0

I have an ASP.NET Core 1.1 application which uses dependency injection and is splitted in 3 layers (web, business logic and data access).

I'd like to access to some values of the configuration file in some methods of the business logic layer. Which way would be more correct to keep a clean architecture?

  • Pass the config values as method-parameters while calling the method in the web layer
  • Pass/inject the configuration as constructor-parameter to the class of my business logic layer
  • I'm not familiar with the framework you're using, but usually DI frameworks provide a way of passing configuration settings to properties of the objects they're creating, which is the general recommended approach for this problem. – Jules Feb 22 '18 at 9:58
  • 1
    I don't understand the question. Passing values as parameters IS injecting. Do you mean passing in as constructor args rather then method args? – candied_orange Feb 22 '18 at 10:19
  • @CandiedOrange yes, that's what I meant – Dario Feb 22 '18 at 10:22
  • @Dario then please edit the question so it makes sense even without these comments. – candied_orange Feb 22 '18 at 10:24
  • @CandiedOrange done – Dario Feb 22 '18 at 10:45
2

In any situation where information needs injecting into part of an app, remember the "tell, don't ask" principle.

If you pass configuration into the business logic layer directly, then you are creating a coupling between the two. It becomes difficult to change the configuration without breaking the business logic layer. Further, you potentially create the need to have to mock the configuration for testing purposes.

However, having to pass individual configuration values as parameters into every business layer method call from the web layer creates other problems. It adds extra complexity to those method signatures and ceremony to using them and it also necessitates exposing all of the configuration to all of the web layer. Again, remember "tell, don't ask": parts of the web layer should only be told about those aspects of configuration that they need to know about.

So I'd suggest a third approach. Inject the configuration values required by each class within the business logic layer, as parameters to their constructors. That way it becomes the responsibility of your IoC framework, if you are using one (or your dependency mapping code at app start if you are using pure DI) to route individual values to just those classes that need them.

  • maybe highlight your solution a bit more? like super bold + italics – Ewan Feb 22 '18 at 10:29
  • I like this idea. Taking it a step further the BLL could define an interface declaring the config values it needs, that the consumers of the service would have to provide. You could then add a singleton in startup.cs DI with config values, or gin-up something custom in your tests. – kitsu.eb Dec 14 '18 at 19:18
0

You can declare the configuration per module and have it provided/injected on creation:

package: Accounts
   + AccountService
   + // internal classes
   + AccountConfig
package: Users
   + UserService
   + // internal classes
   + UserConfig
package: Config
   + IConfigProvider
   + XMLConfigProvider
   + RemoteConfigProvider

Let each module declare an interface (with getters for config values), for its own configuration data. The implementation of this interface must be passed to each module on initialization/construction. You can further break down module config interface for more fine mapping.

Now you implement a configuration provider that provides implementations for each of such interfaces whenever required. The provider might be parsing actual values from a JSON/XML file or from other sources.

When you add another config value to any config interface, the provider interface and implementations have to be updated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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