C# .Net Web Api 2.2终结点中的依赖项注入不可用

C# .Net Web Api 2.2终结点中的依赖项注入不可用,c#,asp.net-web-api,dependency-injection,.net-core,C#,Asp.net Web Api,Dependency Injection,.net Core,我有一个控制台应用程序,它的工作原理类似于web api。 我在Program.cs注册 var collection = new ServiceCollection(); collection.AddScoped<IInfoBusinessComponent, InfoBusinessComponent>(); 为什么构造函数没有得到依赖注入,或者为什么构造函数没有被调用? public class Program { #region fields and propetr

我有一个控制台应用程序,它的工作原理类似于web api。 我在Program.cs注册

var collection = new ServiceCollection();
collection.AddScoped<IInfoBusinessComponent, InfoBusinessComponent>();
为什么构造函数没有得到依赖注入,或者为什么构造函数没有被调用?

public class Program
{
    #region fields and propetries
    public IConfiguration Configuration { get; }  
    //# if DEBUG
    //#endif
    public static IConnection Connection { get; set; }
    public static ITimeSeriesBusinessComponent TimeSeriesBusinessComponent { get; set; }
    public static IInfoBusinessComponent InfoBusinessComponent { get; set; }
    private static int counter;
    #endregion fields and propetries

    public static void Main(string[] args)
    {
        IConfiguration config = GetConfigurations();
        ILogger logger = GetLogger();
        ServiceProvider appServiceProvider = GetServiceProvider(config);

        Parallel.Invoke
        (
            () =>
            {
                BuildWebHost(args).Build().Run();
            }, 
            () =>
            {
                //...
            }
        );


    }

    private static IConfiguration GetConfigurations()
    {
        var builder = new ConfigurationBuilder()
                        .SetBasePath(Directory.GetCurrentDirectory())
                        .AddJsonFile("appsettings.json");

        IConfiguration config = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", true, true)
            .Build();
        return config;
    }

    private static ILogger GetLogger()
    {
        ILogger logger = new LoggerFactory().AddNLog().CreateLogger<Program>();
        return logger;
    }

    private static ServiceProvider GetServiceProvider(IConfiguration config)
    {
        var collection = new ServiceCollection();
        collection.AddLogging(configuration => configuration.AddNLog());
        //...
        collection.AddScoped<IInfoRepository>(serviceProvider =>
        {
            return new InfoRepository(
                config["ConnectionStrings:MainConnection"], 
                config["ConnectionStrings:MetaDataConnection"],
                config["InfoFunctionName"],
                config["UserName"],
                config["Password"],
                config["VirtualHost"],
                config["ConnectionHostName"]);
        });
        collection.AddScoped<IInfoBusinessComponent, InfoBusinessComponent>();
        var appServiceProvider = collection.BuildServiceProvider();
        return appServiceProvider;
    }

    public static IWebHostBuilder BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseApplicationInsights()
            .UseUrls("http://0.0.0.0:5003")
            .UseNLog();
}

问题在于,您使用
BuildWebHost
创建的端点使用了自己的
ServiceProvider
实例。您创建的
ServiceProvider
实例未进入管道

原因:
servicecolection
不使用任何类型的单例注册表,因此通过
servicecolection
的某个实例注册服务并构建
ServiceProvider
的某个实例是不够的。您必须使端点使用您的特定实例
servicecolection
/
ServiceProvider
。或者,您可以将您的
ServiceCollection
复制到端点使用的集合中—我就是这样解决的

因此,让我们使用
servicecolection
来注册您的服务(现在就是这样)。然后,我们不必执行
collection.BuildServiceProvider()
,而是使用
Startup
中的
servicecolection
,将所有注册复制到管道使用的服务集合中

首先,让我们公开您的
服务集合
,以便从
启动
进行访问:

类程序
{
公共静态ServiceCollection AppServices{get;set;}
公共静态void Main(字符串[]args)
{
//…其他东西。。。
AppServices=GetServiceCollection(配置);
//…其他东西。。。
}
//从GetServiceProvider重命名
私有静态ServiceCollection GetServiceCollection(IConfiguration配置)
{
var collection=newservicecolection();
//…注册服务。。。
回收;
}
}
然后在
Startup
类中,使用
ConfigureServices()
中的
Program.AppServices
,如下所示:

编辑:注意在Startup.cs中使用s的

//确保这些用法存在:
使用Microsoft.Extensions.DependencyInjection;
使用Microsoft.Extensions.DependencyInjection.Extensions;
....
公营创业
{
//……其他成员。。。
public void配置服务(IServiceCollection服务)
{
//…像services.AddMvc()这样的常见内容。。。
//添加此行:
服务.TryAdd(Program.AppServices);
}
//……其他成员。。。
}

问题在于,您使用
BuildWebHost
创建的端点使用自己的
ServiceProvider
实例。您创建的
ServiceProvider
实例未进入管道

原因:
servicecolection
不使用任何类型的单例注册表,因此通过
servicecolection
的某个实例注册服务并构建
ServiceProvider
的某个实例是不够的。您必须使端点使用您的特定实例
servicecolection
/
ServiceProvider
。或者,您可以将您的
ServiceCollection
复制到端点使用的集合中—我就是这样解决的

因此,让我们使用
servicecolection
来注册您的服务(现在就是这样)。然后,我们不必执行
collection.BuildServiceProvider()
,而是使用
Startup
中的
servicecolection
,将所有注册复制到管道使用的服务集合中

首先,让我们公开您的
服务集合
,以便从
启动
进行访问:

类程序
{
公共静态ServiceCollection AppServices{get;set;}
公共静态void Main(字符串[]args)
{
//…其他东西。。。
AppServices=GetServiceCollection(配置);
//…其他东西。。。
}
//从GetServiceProvider重命名
私有静态ServiceCollection GetServiceCollection(IConfiguration配置)
{
var collection=newservicecolection();
//…注册服务。。。
回收;
}
}
然后在
Startup
类中,使用
ConfigureServices()
中的
Program.AppServices
,如下所示:

编辑:注意在Startup.cs中使用
s的

//确保这些用法存在:
使用Microsoft.Extensions.DependencyInjection;
使用Microsoft.Extensions.DependencyInjection.Extensions;
....
公营创业
{
//……其他成员。。。
public void配置服务(IServiceCollection服务)
{
//…像services.AddMvc()这样的常见内容。。。
//添加此行:
服务.TryAdd(Program.AppServices);
}
//……其他成员。。。
}

Startup类是什么样子的?我不知道appServiceProvider是如何进入管道的…@felix-b我在最初的帖子中添加了Startup.cs。你说你看不到我的appServiceProvider是如何进入管道的。我假设设置collection.addScope()足以让软件了解并使用依赖项注入对象。我将在ConfigureServices方法中管理我的所有服务。。。。这就是这个方法的初衷,你的启动类是什么样子的?我不知道appServiceProvider是如何进入管道的…@felix-b我在最初的帖子中添加了Startup.cs。你说你看不到我的appServiceProvider是如何进入管道的。我假设设置collection.addScope()足以让软件了解并使用依赖项注入对象。我将在ConfigureServices方法中管理我的所有服务。。。。这就是这种方法的初衷谢谢你的文章Felix!我的服务对象上不存在TryAdd()方法。此外,Add()不起作用,AddService()o
    public InfoController()
public class Program
{
    #region fields and propetries
    public IConfiguration Configuration { get; }  
    //# if DEBUG
    //#endif
    public static IConnection Connection { get; set; }
    public static ITimeSeriesBusinessComponent TimeSeriesBusinessComponent { get; set; }
    public static IInfoBusinessComponent InfoBusinessComponent { get; set; }
    private static int counter;
    #endregion fields and propetries

    public static void Main(string[] args)
    {
        IConfiguration config = GetConfigurations();
        ILogger logger = GetLogger();
        ServiceProvider appServiceProvider = GetServiceProvider(config);

        Parallel.Invoke
        (
            () =>
            {
                BuildWebHost(args).Build().Run();
            }, 
            () =>
            {
                //...
            }
        );


    }

    private static IConfiguration GetConfigurations()
    {
        var builder = new ConfigurationBuilder()
                        .SetBasePath(Directory.GetCurrentDirectory())
                        .AddJsonFile("appsettings.json");

        IConfiguration config = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", true, true)
            .Build();
        return config;
    }

    private static ILogger GetLogger()
    {
        ILogger logger = new LoggerFactory().AddNLog().CreateLogger<Program>();
        return logger;
    }

    private static ServiceProvider GetServiceProvider(IConfiguration config)
    {
        var collection = new ServiceCollection();
        collection.AddLogging(configuration => configuration.AddNLog());
        //...
        collection.AddScoped<IInfoRepository>(serviceProvider =>
        {
            return new InfoRepository(
                config["ConnectionStrings:MainConnection"], 
                config["ConnectionStrings:MetaDataConnection"],
                config["InfoFunctionName"],
                config["UserName"],
                config["Password"],
                config["VirtualHost"],
                config["ConnectionHostName"]);
        });
        collection.AddScoped<IInfoBusinessComponent, InfoBusinessComponent>();
        var appServiceProvider = collection.BuildServiceProvider();
        return appServiceProvider;
    }

    public static IWebHostBuilder BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseApplicationInsights()
            .UseUrls("http://0.0.0.0:5003")
            .UseNLog();
}
public class Startup
{
    public IConfiguration Configuration { get; }

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info
            {
                Title = "My CLI"
            });
        });
        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My CLI");
            c.DocExpansion(Swashbuckle.AspNetCore.SwaggerUI.DocExpansion.None);
            c.RoutePrefix = string.Empty;
        });

        app.UseMvc();
    }
}