Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I inject dependency in webapi in .net framework using Microsoft.Extensions.DependencyInjection?

I am trying to inject my logger as dependency in a .Net Framework 4.7.2 web api project by following these instructions:

https://scottdorman.blog/2016/03/17/integrating-asp-net-core-dependency-injection-in-mvc-4/

This works great for MVC web application but fails on the webapi project with the "parameterless constructor missing" error.

How do I successfully inject using just the default assembly: Microsoft.Extensions.DependencyInjection in framework?

public class Startup
{
    public void Configuration(IAppBuilder app)
    {

        var services = new ServiceCollection();
        ConfigureServices(services);
        var resolver = new DefaultDependencyResolver(services.BuildServiceProvider());
        DependencyResolver.SetResolver(resolver);
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersAsServices(typeof(Startup).Assembly.GetExportedTypes()
            .Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
            .Where(t => typeof(IController).IsAssignableFrom(t)
                        || t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)));
        services.AddSingleton<IMyInterface , MyClass>();
    }
}
public class DefaultDependencyResolver : IDependencyResolver
{
    protected IServiceProvider serviceProvider;

    public DefaultDependencyResolver(IServiceProvider serviceProvider)
    {
        this.serviceProvider = serviceProvider;
    }

    public object GetService(Type serviceType)
    {
        return this.serviceProvider.GetService(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return this.serviceProvider.GetServices(serviceType);
    }
}

public static class ServiceProviderExtensions
{
    public static IServiceCollection AddControllersAsServices(this IServiceCollection services,
        IEnumerable<Type> controllerTypes)
    {
        foreach (var type in controllerTypes)
        {
            services.AddTransient(type);
        }

        return services;
    }
}

Getting "Parameterless constructor is missing" error with an injection like this:

private IMyInterface _my;
public HomeController(IMyInterface my)
{
    _my= my;
}
like image 432
user8808262 Avatar asked Jun 19 '26 05:06

user8808262


1 Answers

Registration Explanation

One issue is that you are registering your DependencyResolver with the MVC resolver registration API which unfortunately is different from the WebAPI resolver registration API. What you want to do instead is:

public void Configuration(IAppBuilder app)
{    
    var services = new ServiceCollection();
    ConfigureServices(services);
    var resolver = new DefaultDependencyResolver(services.BuildServiceProvider());
    HttpConfiguration config = new HttpConfiguration();
    config.DependencyResolver = resolver;
    app.UseWebApi(config);
}

Also note that the IDependencyResolver interface is defined separately in System.Web.Http, so your DefaultDependencyResolver class needs to be updated to derive from it instead.

One thing that has changed on that interface is that there is a BeginScope API. To implement that, call the CreateScope Extension Method exposed on IServiceProvider in Microsoft.Extensions.DependencyInjection to get a new scope. Then pass the provider from that scope to a new instance of your DefaultDependencyResolver.

    public IDependencyScope BeginScope()
    {
        return new DefaultDependencyResolver(this.serviceProvider.CreateScope().ServiceProvider);
    }

Full Example

The blog example you were following for MVC was using OWIN. When I set out to make a full example, I hit the same error as you, and it was because I hadn't correctly configured OWIN so Startup was never being called. Here is a full working example of Microsoft.Extensions.DependencyInjection being used to inject into both MVC and WebAPI Controllers:

https://github.com/ryandle/MVC_WebApi_DI_Example

like image 156
RyanY Avatar answered Jun 21 '26 19:06

RyanY



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!