4
votes

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

1
Have you tried defining a public constructor with no parameters in the UploadController class? - Paul
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. - Shyju
@Paul I do not wish to define a parameterless constructor. I thought that was the point of DI in the first place - JMon
@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 - JMon
Can you share how to do it right? I have the same issue. - klaydze

1 Answers

5
votes

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...