Handling Configuration in ITOps service

In the Advanced Distributed Systems Design (ADSD) Course, Udi talks about the ITOps-service being responsible for things like authentication, connection strings and such.
Dow this mean that you should put all configuration in the ITOps service? Looking at the example for the Composite UI application, we have a Web app called Divergent.Website. At run time the ITOps stuff will run in the Divergent.Website process. In a production Environment, should you create something in the ITOps service that is responsible for the configuration?
If one of the services in the system needs to connect to a database, should that service ask ITOps about what the connection string is, instead of having it in its own appsettings file?

And, in the Append method of each ViewModelComposition it says “// Hardcoded for simplicity. In a production app, a config object could be injected.”. That config object, should that come from ITOps or from the Web app process that the View Model Composition projects run in? I would probably put the configuration in the Divergent.Website appsettings.json file but is that wrong from an ITOps perspective?

Don’t know if I explain my questions good enough. Trying to get my head around how to use configuration and ITOps.

Hi anders,

The way I tend to think about this is that the business code should not be concerned with the technical details of configuration. It’s up to the IT/Ops services to decide where configuration comes from, and any policies associated with it. I would say that the configuration object belongs to the service that uses it, but that ITOps may impose some conventions on it.

For instance, I often include some code in my dependency injection container to fill properties from configuration if the class name ends in Settings. You could do something similar with a marker interface (like IMessage, IEvent, and ICommand in NServiceBus) instead. The configuration class belongs to the service. The dependency injection container extension that fills the class belongs to IT/Ops. Both get deployed in your website.

Putting the configuration in the appsettings.json file is an IT/Ops decision. How transparent is that decision to code in other services? If you decide to move the configuration to a database or to Azure App Configuration, how much of the code base do you need to update? Ideally you make the change in one spot (inside IT/Ops) and everything now has access to the new configuration option. Your business code doesn’t require a change.

The service defines what can be configured. IT/Ops defines how it can be configured.

Let me know if that helps.

-Mike

Hi Mike,
Thank you for the thorough explanation.

Do I understand you correctly that each service that needs som kind of configuration then needs a reference (direct or indirect) to the IT/Ops service?

/Anders

Hi Anders,

Sorry for the late reply. It seems it got stuck in a draft form and never got published.

There does need to be some kind of interaction here but ideally you want to keep it minimal and if possible, unchanging. A change to one service should not lead to a change in the other service, otherwise you have tight coupling between the two services. That’s why I like to rely on something like the DI Container to wire these things together.

The service doesn’t know anything about configuration. It never calls Configuration.GetMyConfiguration() or anything else of that nature. It expresses a dependency on some configuration object and it assumes it will get one when it is created.

The definition of the configuration object belongs to the service that uses the configuration. i.e. It knows which properties and methods are needed to configure the service.

Once we have that, we need some way to ensure that object gets filled from configuration by the container, when it is resolved. This is the job of IT/Ops and there’s a few ways to do it.

One way might be to have a marker interface of some kind to identify configuration objects. Then the IT/Ops service can include code to scan for types with that marker interface and then fill them in from whatever configuration sources are available at runtime when the object is resolved. This is a very weak direct reference as IT/Ops has to make the marker interface available and the service needs to take a dependency on it.

If the marker interface changes (for any reason) then the service needs to be updated as well. Sometimes this can be something as simple as the shared configuration package updating it’s version number. Sometimes this is resolved by putting very stable abstractions (like marker interfaces) into their own assembly package. This stable abstractions code still belongs to the IT/Ops service but it doesn’t change very frequently, making it safer for other services to depend on.

An even weaker reference is a naming convention. i.e. IT/Ops can say that it will apply configuration to any class with a Settings suffix when it is resolved from the container. Only if this suffix needs to change (which seems unlikely) does the service need to change anything.

I hope that helps.

Regards,
Mike