2

I am registering a load of dependencies like so.

container.RegisterTypes(AllClasses.FromLoadedAssemblies(),
WithMappings.FromMatchingInterface,
WithName.Default,
overwriteExistingMappings: true);

This registers things fine and the web api endpoints are properly configured. If I do iisreset or simply wait for a bit then things fail with

The error message is not terribly helpful

"exceptionMessage": "An error occurred when trying to create a controller of type 'ApiController'. Make sure that the controller has a parameterless public constructor.",

Which of course the controller does not, and should not, have.

I am not sure what is going on... but if I register the dependencies explicitly

 container.RegisterType<IDoAThing, Domain.Things.DoAThing>(new HierarchicalLifetimeManager());

Then it all works.

How can I get the 'by convention' registration to keep working?

Loofer
  • 6,841
  • 9
  • 61
  • 102
  • Maybe the assemblies have not been loaded yet into the app domain after iisreset by the time your Unity registration kicks in. Try getting the referenced assemblies with [`BuildManager.GetReferencedAssemblies`](https://msdn.microsoft.com/en-us/library/system.web.compilation.buildmanager.getreferencedassemblies.aspx) method to obtain a list of assemblies in the bin folder and pass this collection to the AllClasses.FromAssemblies helper method. Worst case you could use a well-known class from each of your assemblies, then register classes in those assemblies. – Daniel J.G. May 18 '15 at 18:47
  • See a similar issue where the assemblies were not yet loaded in the app domain [here for example](http://stackoverflow.com/questions/3552223/asp-net-appdomain-currentdomain-getassemblies-assemblies-missing-after-app) – Daniel J.G. May 18 '15 at 18:52
  • I have not got it working yet, but this looks likely. If you made it an answer I would upvote you for sweet sweet internet points! – Loofer May 19 '15 at 09:13
  • Glad to see it helped, hopefully it will help you fixing the issue. I suspected this was the issue because I had a similar issue in the past but I couldn't really try it yesterday – Daniel J.G. May 19 '15 at 10:14

1 Answers1

4

Looks like after the iisreset, the assemblies have not been loaded yet into the app domain by the time your Unity registration kicks in.

Since you are using the helper method AllClasses.FromLoadedAssemblies(), it will not register classes in assemblies that were not yet loaded.

Try getting the referenced assemblies with BuildManager.GetReferencedAssemblies, which will obtain a list of assemblies in the bin folder. Then perform your Unity registrations using those assemblies and the AllClasses.FromAssemblies helper method.

.RegisterTypes(
    AllClasses.FromAssemblies(
             BuildManager.GetReferencedAssemblies().Cast<Assembly>()),
    WithMappings.FromMatchingInterface,
    WithName.Default,
    overwriteExistingMappings: true);   

In the worst case you could use a well-known class from each of your assemblies, getting its assembly via reflection and use it for your registration as in this simplified sample:

.RegisterTypes(
    AllClasses.FromAssemblies(typeof(Foo).Assembly),
    WithMappings.FromMatchingInterface,
    WithName.Default,
    overwriteExistingMappings: true);
Daniel J.G.
  • 34,266
  • 9
  • 112
  • 112