merken / Prise

A .NET Plugin Framework.
https://merken.github.io/Prise
MIT License
362 stars 39 forks source link

Add and retrieve different implementations of a interface? #35

Closed reworc closed 3 years ago

reworc commented 4 years ago

if you have

public interface IService { }  
public class ServiceA : IService { }
public class ServiceB : IService { } 

usually, one can register different implementations of an interface with the ServiceCollection:

services.AddSingleton<IService, ServiceA>();
services.AddSingleton<IService, ServiceB>();

and later retrieve a list of different implementations by

using Microsoft.Extensions.DependencyInjection;

var services = serviceProvider.GetServices<IService>();
var serviceB = services.First(o => o.GetType() == typeof(ServiceB)); 

// or (if IService has a Name property)

var serviceZ = services.First(o => o.Name.Equals("Z"));

However, when using Prise

services.AddPrise<IService>(options =>
   options.WithPluginPath(path).
   WithPluginAssemblyName(name), ServiceLifetime.Singleton);

it is possible to register different implementations of the same interface, but GetServices() only returns the last registered entry.

Do I miss some specific configuration / options or is there a (clean) workaround ?

merken commented 4 years ago

Hi,

For the moment, multi-registration is not supported this way. You could use Assembly Scanning to achieve the same goal, but if you'd like to setup a different configuration per registration, I'm afraid it won't work. The last registration would overwrite the previous.

Using Assembly Scanning, you could potentially have multiple implementations of the same plugin Contract, you can resolve them using an IEnumerable of the Contract.

Please find the consuming injection here: https://github.com/merken/Translation.Plugins/blob/master/Translation.Plugins.Api/Translation.Plugins.Api/Controllers/TranslationController.cs#L30

And the registration here: https://github.com/merken/Translation.Plugins/blob/master/Translation.Plugins.Api/Translation.Plugins.Api/Startup.cs#L39

Does this solve your problem?