Dependency injection with runtime loaded assembly

567 views Asked by At

I have an main application which start with several services. In the following example, there is only two services :

public static void Main(string[] args)
{
    var services = new ServiceCollection();
    services.AddLogging();
    services.AddSingleton<IDemo, Demo>();
    Provider = services.BuildServiceProvider();

    Console.WriteLine("ok");
}

this app has a "addin" folder. and at start, it load all addin available in the folder like this :

private static IEnumerable<Type> LoadAddin()
{
var basePath = $@"{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}\addin";

var dir = new DirectoryInfo(basePath);
if (!dir.Exists)
    dir.Create();

var addins = new List<Type>();

//Loop over all subfolder in the Addin folder
foreach (var subDirectory in dir.GetDirectories())
{
    //Loop over all file
    foreach (var file in subDirectory.GetFiles())
    {
        try
        {
            //load assembly
            var myDll = Assembly.LoadFrom(file.FullName);
            var types = myDll.GetExportedTypes();

            //Check if any type inside the dll match IExt
            foreach (var type in types)
            {
                if (type.GetInterface(nameof(IExt)) == null) continue;
                    addins.Add(type);
            }
        }
        catch (Exception e)
        {
            // ignored
        }
    }
}

after this I correctly get all the addins. Every addinshave a starting method to load specific services and they all share the common service "IDemo".

public IAddin Start(IServiceCollection services)
{
    services.AddLogging();
    services.AddSingleton<IAddin, Test>();

    var provider = services.BuildServiceProvider();

    return provider.GetService<IAddin>();
}

and my main is now :

public static void Main(string[] args)
{
    var services = new ServiceCollection();
    services.AddLogging();
    services.AddSingleton<IDemo, Demo>();
    Provider = services.BuildServiceProvider();
    var addins = LoadAddin();
    foreach (var ext in addins)
    {
        var t = (IExt)ActivatorUtilities.CreateInstance(Provider, ext);
        t.Start(services);
    }
    Console.WriteLine("ok");
}

and here is the problem. I got this exception :

System.MissingMethodException: Method not found: 'Microsoft.Extensions.DependencyInjection.IServiceCollection Microsoft.Extensions.DependencyInjection.LoggingServiceCollectionExtensions.AddLogging(Microsoft.Extensions.DependencyInjection.IServiceCollection)'.
  at Ext.Init.Start(IServiceCollection services)
  at ConsoleApplication1.Program.Main(String[] args) dans **\Program.cs:ligne 25

If I add the reference of my project and add it without the ActivatorUtilities it works but I need to be able to load it on the fly. AndI can't find the catch. the only solution I found is to remove AddLogging from my addin but it's not a real solution because I still need the ILogger in the addin.

Any idea ?

EDIT Here is the sln folder

0

There are 0 answers