4

I am using Unity to do my DI and I have encountered the following error:-

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

I have the following UnityResolver:-

public class UnityResolver : IDependencyResolver, IDependencyScope, System.Web.Http.Dependencies.IDependencyResolver
{
    protected IUnityContainer container;

    public UnityResolver(IUnityContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }
        this.container = container;
    }

    public object GetService(Type serviceType)
    {
        try
        {
            return container.Resolve(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return container.ResolveAll(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return new List<object>();
        }
    }

    public IDependencyScope BeginScope()
    {
        var child = container.CreateChildContainer();
        return new UnityResolver(child);
    }

    public void Dispose()
    {
        container.Dispose();
    }
}

}

I have created a UnityConfig as follows:-

public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        // e.g. container.RegisterType<ITestService, TestService>();

        BuildUnityContainer();
        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    }

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

        // register all your components with the container here
        // you don't need to register controllers
        container.RegisterType<IFileHelpers, FileHelpers>();
        container.RegisterType<IDatabaseHelper, DatabaseHelper>();
        container.RegisterType<IPlayersHelpers, PlayersHelpers>();
        container.RegisterType<IBaseRepository, BaseRepository>();
        container.RegisterType<IAttribsRepository, AttribsRepository>();
        container.RegisterType<IPlayerRepository, PlayerRepository>();
        container.RegisterType<IFileRepository, FileRepository>();
        container.RegisterType<IPlayerAttribsRepository, PlayerAttribsRepository>();

        container.RegisterType<FMContext>();
        container.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager());
        container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new HierarchicalLifetimeManager());

        return container;
    }
}

}

Im initializing everyting in the WebApiConfig.cs

    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        // Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

        // Web API configuration and services
        var container = new UnityContainer();
        UnityConfig.RegisterComponents();
        config.DependencyResolver = new UnityResolver(container);

        config.EnableCors();

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

And this is my UploadController class:-

    public class UploadController : ApiController
{
    private readonly IFileHelpers _fileHelpers;
    private readonly IDatabaseHelper _databaseHelper;
    private readonly IPlayersHelpers _playersHelpers;

    public UploadController(IFileHelpers fileHelpers, IDatabaseHelper databaseHelper, IPlayersHelpers playersHelpers)
    {
        _fileHelpers = fileHelpers;
        _databaseHelper = databaseHelper;
        _playersHelpers = playersHelpers;
    }

    public async Task<HttpResponseMessage> Post()
    {........................}

Can you please help me in determining what am I doing wrong. Do I need to declare something else for this to work?

Thanks for your help and time

5
  • Have you tried defining a public constructor with no parameters in the UploadController class? Commented Sep 2, 2016 at 21:04
  • This error usually occur when DI framework is not able to resolve the concrete implementation of an interface. Make sure you have the mapping( interface to concrete implementation) defined without any errors. Commented Sep 2, 2016 at 21:30
  • @Paul I do not wish to define a parameterless constructor. I thought that was the point of DI in the first place Commented Sep 2, 2016 at 21:32
  • @Shyju can you give me an example since I have not understood what you said exactly. As far as I know I have created all the mappings for all the interfaces I have created Commented Sep 2, 2016 at 21:32
  • Can you share how to do it right? I have the same issue. Commented Nov 7, 2016 at 8:45

1 Answer 1

5

In your Register method, you have the following code:

// ...
// Web API configuration and services
var container = new UnityContainer();
UnityConfig.RegisterComponents();
config.DependencyResolver = new UnityResolver(container);

However, there is nothing registered to that container. There is a separate container (with registrations) being created in your static UnityConfig class, but that container is not being passed to the UnityResolver object...

Sign up to request clarification or add additional context in comments.

3 Comments

You are right Rob! Changed my code and it worked! Thanks a lot
Good to hear @Johann!
My solution looks something like... config.DependencyResolver = new UnityDependencyResolver(UnityBootstrapper.GetConfiguredContainer()); But yeah, the container wasn't available to the controller until I did this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.