1

First time using MS Unity. I have a controller with the following constructor:

 protected IAdministrationService AdministrationService { get; set; }

 public GenerateCacheController(IAdministrationService administrationService)
 {
    AdministrationService = administrationService;
 }

I get the following error when trying to run the project:

Make sure that the controller has a parameterless public constructor.

In my Bootstrpper.cs file I have the following in the RegisterTypes method:

container.RegisterType<GenerateCacheController>();

I still get the error. Am I missing anything else? I'm using ASP.NET MVC 5 and Unity 3.

Here's my Boostrapper.cs file:

 public static class Bootstrapper
{
    public static IUnityContainer Initialise()
    {
        var container = BuildUnityContainer();
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        return container;
    }

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();
        RegisterTypes(container);
        return container;
    }

    public static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterInstance(container);
        var im = new InjectionMember[0];
        container.RegisterType<IAdministrationService, AdministrationService>("AdministrationService", im);
        container.RegisterType<ILookupMapper, LookupMapper>("LookupMapper", im);
        container.RegisterType<IEmailService, EmailService>("EmailService", im);

        container.RegisterType<GenerateCacheController>();

        var provider = new UnityServiceLocator(container);
        ServiceLocator.SetLocatorProvider(() => provider);
    }
}

Abbreviated version of the AdministrationService class:

 public class AdministrationService : IAdministrationService
{
    protected ILookupMapper LookupMapper { get; set; }
    protected IEmailService EmailService { get; set; }

    public AdministrationService(ILookupMapper lookupMapper, IEmailService emailService)
    {
        LookupMapper = lookupMapper;
        EmailService = emailService;
    }
}
Mike
  • 2,561
  • 7
  • 34
  • 56
  • add a parameterless public constructor ? – Selman Genç Dec 04 '14 at 16:36
  • @Selman22 - that is not the right answer. The error is occurring because MS unity is not "injecting" anything into the constructor, which is what it should be doing (and removing the need for a parameterless constructor). However, I only have experience in Ninject and not Unity, so I cannot tell what is not configured correctly for the OP – Tommy Dec 04 '14 at 16:41
  • Show your `AdministrationService` class. – haim770 Dec 04 '14 at 16:41
  • do you use the same container instance for resolving? – thumbmunkeys Dec 04 '14 at 16:44
  • Can you take a look at this and the linked answer and verify if it solved it for you? I had this same issue some time ago. http://stackoverflow.com/questions/24254189/webapi-make-sure-that-the-controller-has-a-parameterless-public-constructor – Jeroen Vannevel Dec 04 '14 at 16:47
  • 1
    When is `Bootstrapper.Initialise()` getting called? That should either be in the `Application_Start` (above everything else) or wired-up using `WebActivatorEx` `PreApplicationStart`. – Brad Christie Dec 04 '14 at 16:49
  • In Application_Start(). – Mike Dec 04 '14 at 16:50
  • @Mike: Wasn't this all wired up when you installed `Unity.Mvc`? (I thought that package was pre-scaffolded) – Brad Christie Dec 04 '14 at 16:52
  • If you install Unity and Unity Bootstrapper via NuGet everything is wired up, and you only need to add calls inside the RegisterTypes method. IIRC you should be able to do `container.RegisterType()` without any additional parameters - and it'll work like magic :) – James S Dec 04 '14 at 16:57
  • There's actual 2 problems: you registered named instances, but used the default instances, and you forced Unity to use parameterless constructors. If you wanted to leave the registration mostly alone, you would have needed to change your constructors to: public AdministrationService([Dependency("LookupMapper")]ILookupMapper lookupMapper, [Dependency("EmailService")]IEmailService emailService) and public GenerateCacheController([Dependency("AdministrationService")]IAdministrationService administrationService). For the registrations, don't pass it "im" since that forces the constructor used. – TTat Dec 09 '14 at 22:39

1 Answers1

0

Found the issue.

I commented out the line:

 var im = new InjectionMember[0];
 container.RegisterType<IAdministrationService, AdministrationService>("AdministrationService", im);

and added:

container.RegisterType<IAdministrationService, AdministrationService>();

And that worked because the previous developers were doing something like this:

private IUnityContainer Container { get; set; }

public AdministrationService()
{
    Container = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IUnityContainer>();
}

instead of

protected ILookupMapper LookupMapper { get; set; }
protected IEmailService EmailService { get; set; }

public AdministrationService(ILookupMapper lookupMapper, IEmailService emailService)
{
    LookupMapper = lookupMapper;
    EmailService = emailService;
}

I have to go back to their way to not break existing code. I'll get around to refactoring one day.

Mike
  • 2,561
  • 7
  • 34
  • 56
  • I had a feeling that was the solution because that's how it is configured in my projects as well but I also use the approach where the interfaces are injected through the constructor. I'm not quite sure why that doesn't work for you. – Jeroen Vannevel Dec 04 '14 at 17:25