i have the following code, and when Running this code i can validate that the Client is created in the ConfigureService Method, when ConfigureServices are called.
- Main Question: How can i get the access to clientFactory in the MainAsync Task?
- Secondary Priority: How do i instanciate the serviceColletion through a constructor
namespace CustomeNameSpace
{
public class Program
{
public static IConfigurationRoot configuration;
private static readonly IServiceCollection serviceCollection;
public static void Main(string[] args)
{
ConfigureServices();
ILogger logger = NullLogger.Instance;
MainAsync(logger).GetAwaiter().GetResult();
}
private static async Task MainAsync(ILogger log)
{
// Need to use httpClientAt this location....
// var clientFactory = .....
// var client = clientFactory.CreateClient()
}
public static void ConfigureServices()
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddHttpClient();
var clientFactory = serviceCollection.BuildServiceProvider().GetRequiredService<IHttpClientFactory>();
//var client = clientFactory.CreateClient();
configuration = new ConfigurationBuilder().SetBasePath(Directory.GetParent(AppContext.BaseDirectory).FullName)
.AddJsonFile("local.settings.json", false)
.Build();
}
}
}
CodePudding user response:
This code needs to be refactored to follow a more stream lined approach to applying dependency injection.
public class Program {
//async Task Main feature allowed from C# 7.1
public static async Task Main(string[] args) {
//Composition root
IServiceProvider services = ConfigureServices();
ILogger logger = NullLogger.Instance;
IHttpClientFactory clientFactory = service.GetRequiredService<IHttpClientFactory>();
HttpClient client = clientFactory.CreateClient();
IConfiguration configuration = service.GetRequiredService<IConfiguration>();
await RunAsync(logger, client, configuration);
}
private static async Task RunAsync(ILogger log, HttpClient client, IConfiguration configuration) {
//...
}
public static IServiceProvider ConfigureServices() {
IServiceCollection services = new ServiceCollection();
services.AddHttpClient();
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetParent(AppContext.BaseDirectory).FullName)
.AddJsonFile("local.settings.json", false)
.Build();
services.AddSingleton<IConfigurationRoot>(configuration);
services.AddSingleton<IConfiguration>(configuration);
return services.BuildServiceProvider();
}
}
Note how any required services can now be resolved and used as needed from the service provider.
This could be further improved by encapsulating the primary functionality in a class and resolving it from the service provider so that all explicit dependencies can be resolved and injected directly by the service container.