Little tip for C#/DotNet Dependency Injection in making settings specific to a class

I am currently working on an application which will automate deployment of applications. Specifically, I wrote two applications formerly;

  • IRExecutor - Takes a defined list of applications and executes them sequentially.
  • IRExecutorProcessor - Based upon a configured list of applications, discovers applications, generates a job execution definition file which IRExecutor can use.

This is remarkably awesome, but I found it virtually impossible to manage these applications without a lot of brain power and front-end app.

  • So, I am working on a third application called IRFullDeploy. Originally, this was simply a file which using MSBuild commandline could;
  • Build an application.
  • Deploy it to a target location.
  • Optionally execute that application.

We may ask - why deploy an application and then execute it? Well, fellow midichlorians, I may have;

  • Automated tests to use.
  • Applications themselves used to generate additional applications and files.
  • Further build processes to orchestrate.

The light-bulb moment

It was when trying to piece together all these applications and the IRProcessor framework it was clear that the same configuration used for IRProcessor could manage the deployment of applications. Over the Xmas period, I have been adding functionality to IRFullDeploy to significantly simplify the managing of my batch execution framework for the findigl property platform. More on batch execution 

A cheat way to simplify Dependency Injection and context specific mappings

Whilst developing this application, I found it relevant to create a post on application configuration which I listed on dev.to. The basics of the article was to reduce the overhead of mapping configuration data, and letting developers confidently change the way data is used within an application without breaking it.

This is a very brief code sample on what I did, before I will explain what problem it solves;

The App.Config App Settings Key

<add key="solutionApplication" value="['SolutionBaseDirectory': 'C:\InfoRhino\scraper\ScrapingEngine\Scraper\IRExecutor\', 'BuiltBinaryFolderName': 'Release']"/>

The "Settings" POCO/Interface

public SolutionApplication solutionApplication { get; set; } = ConfigurationManager.AppSettings[nameof(solutionApplication)].GetObjectFromDeserialised <SolutionApplication>();

The usage inside a class. Code snippet.

        public SolutionApplication solutionApplication {get;set;}
        public GenerateBuildableApplication(
            ISetting setting,
            IGetExecutableArtifactPopulationSource getExecutableArtifactPopulationSource
            , IRFullDeploy.Data.Parameter.GenerateExecutableArtifactPopulationSource populationSourceSetting
            )
        {
            this.solutionApplication = setting.solutionApplication;
            this.getExecutableArtifactPopulationSource = getExecutableArtifactPopulationSource;
            this.validConfigExecutableExtensions = validConfigExecutableExtensions;
            this.populationSourceSetting = populationSourceSetting;
        }

Explanation of the significance of the approach

We can think of the ISettings interface, as being a mechanism to define a global settings object. The problem with the global settings approach, is if we start to use ISettings as a public property in consuming classes, it can be hard to know which sub properties are used in a given class. i.e.

public ISetting setting {get;set;}

versus 

public SolutionApplication solutionApplication {get;set;}

By referring to the solutionApplication property, there is no ambiguity on the solutionApplication existing in it's own right. It is decoupled from the settings, but settings can through constructor injection be the setter.

Another big plus is - we can create fakes/mocks of this object for the benefits of unit testing.

I also believe, but would need to do the metrics on this - by decoupling the ISettings class, the GAC can recycle ISettings. Do we care, I doubt it, but it may offer some benefits for performance.

Find out more about Info Rhino - my Limited Company

Add comment