Click here to Skip to main content
15,881,803 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Using .NET Core 6 dependency injection I have code in Program.cs looking like this

C#
...

IConfigurationBuilder configuration = new ConfigurationBuilder();
configuration.SetBasePath(Directory.GetCurrentDirectory());
var host = Host.CreateDefaultBuilder()
    .ConfigureServices((context, services) =>
    {
        services.AddSingleton<IFileLogging, FileLogging>();
    }).Build();
logging = ActivatorUtilities.GetServiceOrCreateInstance<IFileLogging>(host.Services);
logging.Debug(log4net, "Starting up...");
Console.ReadLine();


It works nicely. I get a reference to a singleton for the interface IFileLogging.

Now I'm wondering if there is a way to perform the configuration in an external json file, i.e. moving the line

C#
services.AddSingleton<IFileLogging, FileLogging>();


to a separate json file, i.e. something along the lines

JSON
{
  "components": [
    {
      "type": "DITest.Default_DI_Namespace.FileLogging, DITest",
      "services": [
        {
          "type": "DITest.Default_DI_Namespace.IFileLogging, DITest"
        }
      ],
      "instanceScope": "single-instance",
      "injectProperties": true
    }
  ]
}


I assume that I need to configure my services to get the information from file, but I don't know how.

If anyone has an idea I would be most grateful.

King regards
Magnus

What I have tried:

I've Googled quite a lot, but mostly found how to read settings from appsettings.json for getting data.
Example[^]
Posted
Updated 17-Jan-22 7:12am

 
Share this answer
 
Comments
Magnus Sydoff 17-Jan-22 13:05pm    
Hi _Asif,

Yes, I looked at that article, but if I'm not misreading it, it just gives me a value in return, not wiring up my services.

I have ended up writing my own implementation that reads from a json file and then looks at the defined interfaces and classes and wires it up.

Thanks!
I finally gave up Googling this issue and took a deep look on how the automatic variant of injecting services was made.

I used this NuGet package, AutoRegisterDI[^]
as a starting point and ended up something looking like the code below (some of my own types are not shown for brevity, but I hope the general idea comes across)

C#
Assembly assemblyForInterface = Assembly.LoadFrom(Path.Combine(folderToLoadModulesFrom, config.InterfaceDefinition.FileName));
Assembly assemblyForImplementation = Assembly.LoadFrom(Path.Combine(folderToLoadModulesFrom, config.ConcreteClassImplementation.FileName));

var exportedTypes = assemblyForImplementation.GetExportedTypes();
var implementationClass = exportedTypes.FirstOrDefault(t => t.Name == config.ConcreteClassImplementation.DefinedType && t.IsClass && !t.IsAbstract && !t.IsNested);
if (implementationClass == null)
{
    Console.WriteLine($"* Unable to find implementation {config.ConcreteClassImplementation.DefinedType} in file {config.ConcreteClassImplementation.FileName}. This config will not be used.");
    return;
}
var interfaceForImplementation = assemblyForInterface.GetExportedTypes().FirstOrDefault(t => t.Name == config.InterfaceDefinition.DefinedType && t.IsPublic && !t.IsNested);
if (interfaceForImplementation == null)
{
    Console.WriteLine($"* Unable to find interface {config.InterfaceDefinition.DefinedType} in file {config.InterfaceDefinition.FileName}. This config will not be used.");
    return;
}

if (!(ServiceLifetime.TryParse(typeof(ServiceLifetime), config.ServiceLifetime, out object lifetimeObject)) || (lifetimeObject is null))
{
    Console.WriteLine($"* Unable to parse {nameof(ServiceLifetime)} from value {config.ServiceLifetime}. This config will not be used.");
    return;
}
ServiceLifetime lifetime = (ServiceLifetime)lifetimeObject;

services.Add(new ServiceDescriptor(interfaceForImplementation, implementationClass, lifetime));
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900