Outils pour utilisateurs

Outils du site


developpement:dotnet:msioc

Inversion of Control

En utilisant le package Microsoft.Extensions.DependencyInjection.

Documenté dans le contexte de .NET Core 7.

Lifetimes

  • Singleton:
    • Created once per application
    • The instance will be alive until the service is stopped
    • Disposed of when the application stops
  • Scoped:
    • Initialized when a scope is created
    • Kept alive until scope is disposed
    • Scope is defined for a HTTP request, or expliceitly defined
  • Transient
    • Initialized every time they are requested
    • Instances cannot be shared accoss different components in an application
    • Ideal for retrieving information from a database or API

Example de "container"

Ceci n'est pas exactement le container, mais la configuration d'un container. Ça peut être utilisé dans une couche DDD, par exemple Application ou Infrastructure.

using Microsoft.Extensions.DependencyInjection;
 
namespace Infrastructure;
 
public static class DependencyInjection
{
    public static IServiceCollection AddInfrastructure(this IServiceCollection services)
    {
        services.AddSingleton<IMqttService, MqttService>();
 
        return services;
    }
}

Ensuite avec le builder (Dans Program.cs, on peut faire:

builder.Services
    .AddApplication()
    .AddInfrastructure();

Hosted Service

  • Permet d'exécuter des tâches en arrière-plan
  • Configuré dans ASP.NET Core ou via un modèle Worker Service
  • Worker Service sont faits pour des tâches en arrière-plan
  • Utiliser ASP.NET Core pour ajouter un service hosted
using Microsoft.Extensions.Hosting;
 
public class CustomHostedService: IHostedService, IDisposable
{
    public CustomHostedService()
    {
        Console.WriteLine("ctor");
    }
 
    public async Task StartAsync(CancellationToken cancellationToken)
    {
        Console.WriteLine("Start Async");
 
        await Task.Delay(1000, cancellationToken);
    }
 
    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

Dans la configuration du _container_:

services
    .AddTransient<IHostedService, CustomHostedService>();

_Injecter_ le service manuellement:

app.Services.GetService(typeof(CustomHostedService));

Background Service

using Microsoft.Extensions.Hosting;
 
public class CustomBackgroundService: BackgroundService
{
    public CustomBackgroundService()
    {
        Console.WriteLine("ctor");
    }
 
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        await Task.Delay(1000, stoppingToken);
    }
}

Dans la configuration du _container_:

services
    .AddHostedService<CustomBackgroundService>();

_Injecter_ le service manuellement:

app.Services.GetService(typeof(CustomBackgroundService));

Exemple

protected override async Task ExecuteTask(CancellationToken cancellationToken)
{
 
    while (!cancellationToken.IsCancellationRequested)
    {
        using (var scope = _serviceProvider.CreateScope())
        {
            var productService = scope.ServiceProvider.GetService<IProductService>();
 
        }
    }
}

Exemple exécutable dans LinqPad 7

Language: C# Program, .NET 7.0

void Main()
{
	string[] args = new string[0];
 
	using IHost host = Host.CreateDefaultBuilder(args)
		.ConfigureServices((_, services) =>
			services
				.AddSingleton<ISimpleService, SimpleService>()
				.AddSingleton<BasicService>()
		)
		.Build();
 
	using IServiceScope serviceScope = host.Services.CreateScope();
	IServiceProvider provider = serviceScope.ServiceProvider;
 
	BasicService basicService = provider.GetService<BasicService>();
 
	// host.Run();
 
	Console.WriteLine("End of program");
}
 
#region Services
 
public class BasicService
{
	private readonly ISimpleService _simpleService;
 
	public BasicService(
		ISimpleService simpleService)
	{
		_simpleService = simpleService;
 
		SetupService();
	}
 
 
	private void SetupService()
	{
		_simpleService.SayHello();
	}
}
 
public interface ISimpleService {
	public void SayHello();
}
 
public class SimpleService: ISimpleService
{
	private readonly ISimpleService _simpleService;
 
	public SimpleService() {}
 
	public void SayHello()
	{
		Console.WriteLine("Hello");
	}
}
 
#endregion
developpement/dotnet/msioc.txt · Dernière modification : 2023/06/19 18:43 de sgariepy