I have the class package
with a type, plus more info not relevant to the question
public class Package
{
public string Type { get; set; }
// ... more package properties
}
I have the following interface service to mail packages
public interface IMailService
{
public Task<string> SendPackage(Package package);
}
Then I have several implementations for this interface
public class MailNewPackageService : IMailService
{
public async Task<string> SendPackage(Package package)
{
Console.WriteLine("send package through new service");
// implementation ...
}
}
public class MailOldPackageService : IMailService
{
public async Task<string> SendPackage(Package package)
{
Console.WriteLine("send package through old service");
// implementation ...
}
}
I need a delegate which takes a string
and returns a IMailService
public delegate IMailService MailServiceResolver(string key);
At the startup
we set the service with a key
// we define all the implementations
services.AddSingleton<MailNewPackageService>();
services.AddSingleton<MailOldPackageService>();
// we set the resolver to return a service based on a key
services.AddSingleton<MailServiceResolver>(provider => key =>
{
switch(key)
{
case "new": return provider.GetService<MailNewPackageService>();
case "old": return provider.GetService<MailOldPackageService>();
default: throw new KeyNotFoundException();
}
})
We set the consumer
public class UpsOffice : IUpsOffice
{
private readonly IMailService _mailNewService;
private readonly IMailService _mailOldService;
public class UpsOffice(MailServiceResolver resolver)
{
_mailNewService = resolver("new");
_mailOldService = resolver("old");
}
public async Task<string> ProcessPackage(Package package)
{
// ... conditionals to check which service to use
if(x == true)
{
// ... processing through new service
_mailNewService.SendPackage(package);
} else
{
// ... processing through old service
_mailOldService.SendPackage(package)
}
}
}