【问题标题】:How do I inject dependency in webapi in .net framework using Microsoft.Extensions.DependencyInjection?如何使用 Microsoft.Extensions.DependencyInjection 在 .net 框架中的 webapi 中注入依赖项?
【发布时间】:2019-10-07 15:06:28
【问题描述】:

我正在尝试按照以下说明将我的记录器作为依赖项注入 .Net Framework 4.7.2 web api 项目:

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

这对 MVC Web 应用程序非常有用,但在 webapi 项目上失败并出现“缺少无参数构造函数”错误。

如何在框架中仅使用默认程序集成功注入:Microsoft.Extensions.DependencyInjection

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;
    }
}

使用这样的注入出现“缺少无参数构造函数”错误:

private IMyInterface _my;
public HomeController(IMyInterface my)
{
    _my= my;
}

【问题讨论】:

  • 现在查看您在服务集合中注册IMyInterface 的位置。
  • 你也没有注册web api的依赖解析
  • 请查看更新后的代码。
  • 你能解释一下“你也没有为 web api 注册依赖解析”吗?我该如何/在哪里执行此操作?

标签: c# .net dependency-injection


【解决方案1】:

注册说明

一个问题是您正在使用 MVC 解析器注册 API 注册您的 DependencyResolver,不幸的是 is different from the WebAPI resolver registration API. 您想要做的是:

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);
}

还要注意IDependencyResolver 接口is defined separately in System.Web.Http,因此您的DefaultDependencyResolver 类需要更新为从它派生。

该接口上发生了变化的一件事是有一个BeginScope API。要实现这一点,请调用 Microsoft.Extensions.DependencyInjection 中 IServiceProvider 上公开的 CreateScope Extension Method 以获取新范围。然后将提供程序从该范围传递给 DefaultDependencyResolver 的新实例。

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

完整示例

您关注的 MVC 博客示例使用的是 OWIN。当我开始做一个完整的例子时,我遇到了和你一样的错误,这是因为我没有正确配置 OWIN,所以从来没有调用 Startup。以下是用于注入 MVC 和 WebAPI 控制器的 Microsoft.Extensions.DependencyInjection 的完整工作示例:

https://github.com/ryandle/MVC_WebApi_DI_Example

【讨论】:

  • 谢谢,这有帮助。虽然,我似乎没有得到任何不同的结果。它仍然期待控制器上的无参数构造器。我需要在 BeginScope() 中配置什么?(预计使用 System.Web.Http.Dependencies.IDependencyResolver 实现) public IDependencyScope BeginScope() { throw new NotImplementedException(); }
  • @user8808262 我已经添加了关于实现 BeginScope() 的说明。检查一下,如果您还有其他问题,请告诉我。
  • @RyanY,谢谢。我添加了 CreateScope 以根据您上面的建议获得新的范围,但没有运气。仍然得到无参数构造函数丢失错误。你有什么进一步的想法吗?谢谢!如果你有这样做的代码,你介意在这里分享吗?也许,这可能对我有帮助。谢谢
  • @user8808262 在我的回答中添加了一个完整的示例,希望对您有所帮助!
  • 非常感谢!那是一个巨大的帮助!我很感激。
【解决方案2】:

您是否在 HomeController 上使用[Serializable]?如果是这样,在使用时需要一个不带参数的构造函数。

尝试添加:public HomeController() { } 并再次运行。

更多信息:parameter less constructor error

【讨论】:

  • 没有。但是,如果我添加 public HomeController() { },我的记录器没有配置/注入到构造函数中。
猜你喜欢
  • 1970-01-01
  • 2023-02-02
  • 2021-02-02
  • 2021-06-16
  • 2020-10-25
  • 2010-09-05
  • 2019-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多