0

After checking all the similar questions on SO, my issue persists so I'm opening a new question for it.

I have a unit test that references anther project that contains a MVC 4 ApiController which has a constructor for dependency injection.

public class DataController : ApiController
{
    public DataController(IRepository repository){}    
}

In my test, I'm using Microsoft.Extensions.DependencyInjection and have the following setup:

// Note: this redundant type access is necessary to load controllers from a different assembly,
// see https://stackoverflow.com/a/11758025/1468097
var type = typeof(DataController);

var services = new ServiceCollection().AddSingleton<IRepository>(new ImMemoryRepository());
var httpConfiguration = new HttpConfiguration
{ 
    DependencyResolver = new DependencyResolver(services.BuildServiceProvider()),
    IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
};
httpConfiguration.Routes.MapHttpRoute("Default", "{controller}/{action}");
httpConfiguration.DependencyResolver = new DependencyResolver(services.BuildServiceProvider());
var httpServer = new HttpServer(httpConfiguration);
var client = new HttpClient(httpServer);
var response = await client.GetAsync("http://whatever/data/getdata?id=000");

and I have a fairly barebone implementation of the dependency resolver as nested private class inside the test class:

private class DependencyResolver : IDependencyResolver
{
    private readonly ServiceProvider _serviceProvider;

    public DependencyResolver(ServiceProvider serviceProvider) => _serviceProvider = serviceProvider;

    public void Dispose() => _serviceProvider.Dispose();

    public object GetService(Type serviceType) => _serviceProvider.GetService(serviceType);

    public IEnumerable<object> GetServices(Type serviceType) => _serviceProvider.GetServices(serviceType);

    public IDependencyScope BeginScope() => new Scope(_serviceProvider.CreateScope());

    private class Scope : IDependencyScope
    {
        private readonly IServiceScope _scope;

        public Scope(IServiceScope scope) => _scope = scope;

        public void Dispose() => _scope.Dispose();

        public object GetService(Type serviceType) => _scope.ServiceProvider.GetService(serviceType);

        public IEnumerable<object> GetServices(Type serviceType) => _scope.ServiceProvider.GetServices(serviceType);
    }
}

The response I get from the test is a 500 server error saying

Type 'Mvc.DataController' does not have a default constructor

It seems I'm doing what all the others are doing for dependency injection in MVC 4, even for this question that has a very similar symptom.

Am I missing something obvious here?

Update

I've tried NinjectResolver comes down to the same problem:

var kernel = new StandardKernel();
kernel.Bind<IRepository>().ToConstant(new InMemoryRepository());
var httpConfiguration = new HttpConfiguration
{
    DependencyResolver = new NinjectResolver(kernel)
};

1 Answer 1

0

I figured this out.

The key is that you also need to add the controller you are hitting in your dependency configuration.

In my case, I just need to add:

var services = new ServiceCollection();

// This is what was missing.
services.AddTransient<DataController>();

Taken from here (although I'm not using OWIN at all): How to add Microsoft.Extensions.DependencyInjection to OWIN Self-Hosted WebApi

Another example using Autofac:

var builder = new ContainerBuilder();

// You need to register the assembly that contains your controller.
builder.RegisterApiControllers(typeof(DataController).Assembly);

Taken from here: Dependency injection not working with Owin self-hosted Web Api 2 and Autofac

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

Comments

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.