0

I am loading assemblies from a "plugins" folder and registering some implementations dynamically.

var appPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var pluginsPath = Path.Combine(appPath, path);

var asmfiles = Directory.EnumerateFiles(pluginsPath, "*.dll", SearchOption.AllDirectories);            

foreach(var asmfile in asmfiles)
{
    Assembly.LoadFile(asmfile);
}

After loading all assemblies, I proceed to register the services:

builder.RegisterAssemblyTypes(asms)
       .Where(t => typeof(IValidator).IsAssignableFrom(t))
       .AsClosedTypesOf(typeof(IValidator<>));

builder.RegisterAssemblyTypes(asms)
       .Where(t => typeof(IService).IsAssignableFrom(t) && t.IsClass)
       .AsImplementedInterfaces()
       .AsSelf();

Just to make sure, I log all registrations:

container.ComponentRegistry
         .Registrations
         .SelectMany(x => x.Services)
         .Select(x => x.Description)

2016-07-13 09:58:52.5673 TRACE: Registered services:
    Services.Test.ITestService
    ServiceModel.IService
    Services.Test.TestService
2016-07-13 09:58:52.5673 TRACE: Registered validators:
    TestRequestValidator

Problem is, Autofac can't seem to create a controller with a ITestService dependency in its constructor.

  "type": "Autofac.Core.DependencyResolutionException",
  "message": "None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'ApiHostService.Controllers.EchoController' can be invoked with the available services and parameters: Cannot resolve parameter 'Services.Test.ITestService testService' of constructor 'Void .ctor(Services.Test.ITestService)'.",

What could be the problem?

Edit: resolving from the container fails.

raine
  • 817
  • 1
  • 15
  • 26

1 Answers1

1

I think you might be loading assemblies with same identities twice when you run Assembly.LoadFile(asmfile). This causes the ITestService you're trying to resolve (this is the one in your project reference) to be a different one from the ITestService you've loaded in the container (the one loaded as a separate assembly).

Could you please try using Assembly.LoadFrom(asmfile) instead?

See this question: Difference between LoadFile and LoadFrom with .NET Assemblies?

You can also use this assembly preloader that will achieve what you want without loading duplicates: https://github.com/zidad/net-tools/blob/master/src/Net.Core/Reflection/AssemblyPreloader.cs

Community
  • 1
  • 1
Wiebe Tijsma
  • 10,173
  • 5
  • 52
  • 68
  • That AssemblyPreloader class was pretty useful. :) I eventually decided to build ApiControllers at runtime and use a Mediator to dispatch requests to the correct handlers. After several changes, everything works, but I'm not sure what was the issue. – raine Jul 14 '16 at 12:24