Autofac does not allow assembly scan types in asp.net 5

We have a dnx46 web project that uses startup at startup to register types. Our project.json dependencies include:

"Autofac.Configuration": "4.0.0-rc1-268", "Autofac.Extensions.DependencyInjection": "4.0.0-rc1-177", "Autofac.Extras.CommonServiceLocator": "3.2.0", "Microsoft.AspNet.Hosting": "1.0.0-rc1-final", "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final", "Microsoft.AspNet.Mvc": "6.0.0-rc1-final", "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final", "Microsoft.AspNet.Mvc.ViewFeatures": "6.0.0-rc1-final", "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", "Microsoft.AspNet.Session": "1.0.0-rc1-final", "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final", "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final", "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc1-final", "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final", "Microsoft.Extensions.Logging": "1.0.0-rc1-final", "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final", "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final", "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-rc1-final", "Newtonsoft.Json": "8.0.3" 

Our startup.cs ConfigureServices method is as follows:

 public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddSingleton(serviceType => Configuration); services.AddInstance<Microsoft.Extensions.Configuration.IConfiguration>(Configuration); services.AddCaching(); services.AddSession(); services.AddMvc(); var builder = new ContainerBuilder(); var assemblies = Directory.GetFiles(<ourBinDirectoryPath>, "*.dll", SearchOption.TopDirectoryOnly).Select(Assembly.LoadFrom); foreach (var assembly in assemblies) { builder.RegisterAssemblyTypes(assembly).Where(t => t.Name.EndsWith("Service") || t.Name.EndsWith("Repository") || t.Name.EndsWith("DataContext")).AsSelf().AsImplementedInterfaces(); builder.RegisterAssemblyTypes(assembly).Where(t => !t.Name.EndsWith("Service") && !t.Name.EndsWith("Repository") && !t.Name.EndsWith("DataContext")).AsSelf().AsImplementedInterfaces().InstancePerDependency(); } builder.Populate(services); var container = builder.Build(); return container.Resolve<IServiceProvider>(); } 

Our process is that we have several projects that we collect to remove these DLL files that this project will need in the user bin folder. At startup, we scan these assemblies to register types with Autofac. We did this to prove the conceptual design, and it worked without problems. However, in our new project, we have the following problems:

  • If you try to enable the service in the controller constructor, this will throw an error indicating that the Microsoft Dependency injection cannot resolve the service. Not sure why he is not using the Autofac provider here.
  • If we manually enable one type at startup along with our assembly scan, we get an error in the controller design indicating that Autofac was unable to enable this service (the Autofac provider is used here, but still cannot find our types).
  • If I inspect the linker and container before it returns to ConfigureServices, it seems to register all of our types. However, if I change the controller to implement IServiceProvider, and then try to allow the service from it, it definitely uses the Autofac provider, but I always return null (no service was found).

After trying a lot of things, I took our proof of the draft concept and copied it to our new solution (if we missed some little tweaking or something when creating our new project), and the bad behavior continued. I'm starting to think that our assemblies introduce some errors (since these are the only things that changed after copying), but Autofac does not throw errors during scanning and instead simply does not use the types that it scanned correctly.

Change 1

I created and posted a very simplified example that reproduces the problem I am facing. You must remove this and run it to reproduce the error. You should receive an error message in the constructor of the main controller indicating that the service permission failed.

Note: when running this example, it launches a .bat file that puts the dll output from the domain project into your .nuget folder of your user profile.

Edit 2

Separate the interface into an abstraction folder based on @Travis Illig's recommendation. As soon as I did this, the solution got to work. We divided it into our "real" project, but it does not work. Still experiment to see why.

Edit 3

So finally, our project is working again. The problem ended with a few things:

  • We had a project dependency on abstraction, indicated in our web project, and we also downloaded and looked at the DLLs from this assembly (double loading). (I think it was a big problem.)
  • Our versions of NuGet were bad, so I don’t think they loaded correctly. We used 1.0.0-1, which is an invalid pre-format. Updated to 1.0.0-b1, and everything seemed to work better.

It took me more time to figure out, and my biggest problem at this point is that Autofac fails. I am very sorry that it will not explode and will not give me debugging information or something that indicates a problem. Instead, everything seemed to scan and load the fine, but then, when you went to use the container, it didn't solve anything.

+7
asp.net-mvc autofac
source share
1 answer

Most likely, the assembly is loaded in the order in which some types cannot be loaded due to the inability to load the necessary components.

For example, let's say you have assembly A that contains the IComponent interface. Also say that you have assembly B that contains the Component class that implements IComponent . If you load assembly B first, the Component type will not load because the interface that it implements is not defined.

When performing type scanning, Autofac tries to be as safe as possible and will not explode if it runs into types that cannot be loaded. You can see in the scan registration source where it uses a special safe method for downloading.

In your spike code, I'm sure there were far fewer builds to download, so you downloaded things in the correct order. Happy accident. When you get into larger projects, it is much easier to handle the boot order and cause such problems.

+2
source share

All Articles