在.NET Core 3控制台应用程序中实现Autofac,将IServiceProvider注入Config类(不工作



这可能是一个"愚蠢"的问题,但我有点迷失了方向,我正试图将Autofac实现到一个正常工作的.NET Core 3.1控制台应用程序中,但似乎无法使某些事情正常工作。

我有一个名为Config.cs的类,它在控制台应用程序的多个位置使用,所以我想保留这个文件,以免重写这个实现。

这是文件

public class Config : IConfig
{
readonly IConfiguration _config;
public Config(IServiceProvider services)
{
_config = (IConfiguration)services.GetService(typeof(IConfiguration));
}
public string StorageConnectionString => _config["ConnectionStrings:StorageConnectionString"];
public string SqlConnectionString => _config["ConnectionStrings:SqlConnectionString"];
public string MongoConnectionString => _config["ConnectionStrings:MongoConnectionString"];
public string RayGunApiKey => _config["RayGunApiKey"];
public string ElasticsearchUri => _config["Uris:ElasticsearchUri"];
public string StatsDUri => _config["Uris:StatsDUri"];
public string Get(string key) => _config[key];
}

这首先在Functions.cs中的TimeTrigger:中使用

public class Functions
{
readonly IConfig _config;
public Functions(ILogger<Functions> logger, IConfig config)
{
_logger = logger;
_config = config;
}

public void Run([TimerTrigger("00:00:01", RunOnStartup = true, UseMonitor = true)]TimerInfo myTimer)
{
...
}
}

但是当我启动控制台应用程序时,会抛出一个错误

System.InvalidOperationException: Unable to resolve service for type 'DataPurger.IConfig' while attempting to activate 'DataPurger.Functions'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(Closure , IServiceProvider , Object[] )
at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstance[T](IServiceProvider serviceProvider) in C:projectsazure-webjobs-sdk-rqm4tsrcMicrosoft.Azure.WebJobs.HostExecutorsDefaultJobActivator.cs:line 37
at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstance[T](IFunctionInstanceEx functionInstance) in C:projectsazure-webjobs-sdk-rqm4tsrcMicrosoft.Azure.WebJobs.HostExecutorsDefaultJobActivator.cs:line 32
at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory`1.<>c__DisplayClass1_1.<.ctor>b__0(IFunctionInstanceEx i) in C:projectsazure-webjobs-sdk-rqm4tsrcMicrosoft.Azure.WebJobs.HostExecutorsActivatorInstanceFactory.cs:line 20
at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory`1.Create(IFunctionInstanceEx functionInstance) in C:projectsazure-webjobs-sdk-rqm4tsrcMicrosoft.Azure.WebJobs.HostExecutorsActivatorInstanceFactory.cs:line 26
at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.CreateInstance(IFunctionInstanceEx functionInstance) in C:projectsazure-webjobs-sdk-rqm4tsrcMicrosoft.Azure.WebJobs.HostExecutorsFunctionInvoker.cs:line 44
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ParameterHelper.Initialize() in C:projectsazure-webjobs-sdk-rqm4tsrcMicrosoft.Azure.WebJobs.HostExecutorsFunctionExecutor.cs:line 846
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsyncCore(IFunctionInstanceEx functionInstance, CancellationToken cancellationToken) in C:projectsazure-webjobs-sdk-rqm4tsrcMicrosoft.Azure.WebJobs.HostExecutorsFunctionExecutor.cs:line 117

这种注入在没有Autofac的情况下可以工作,但我"被迫"实现它,因为Autofac在我工作的其他项目中都有使用。

这是程序.cs

static void Main(string[] args)
{
RegisterServices();
CreateHostBuilder(args).Build().RunAsync().Wait();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
config.AddEnvironmentVariables();
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
config.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true,
reloadOnChange: true);
})
.ConfigureLogging((context, b) =>
{
b.AddConsole();
})
.ConfigureServices(s =>
{
s.AddLogging();
s.AddOptions();
})
.ConfigureWebJobs(builder =>
{
builder.AddAzureStorageCoreServices();
builder.AddExecutionContextBinding();
builder.AddTimers();
})
.UseConsoleLifetime()
.UseServiceProviderFactory(new AutofacServiceProviderFactory());
static void RegisterServices()
{
var collection = new ServiceCollection();
var builder = new ContainerBuilder();
builder.RegisterModule<BaseModule>();
builder.Populate(collection);
var container = builder.Build();
_serviceProvider = new AutofacServiceProvider(container);
}
public class BaseModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Config>().As<IConfig>().SingleInstance();
}
}

我做错了什么,我确定有什么东西不见了,或者我没有正确理解?

这是我在Program.cs中的ASP.Net核心3.1的示例。我更改了

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory()) //<-like yours
.UseSerilog()
.ConfigureLogging((context, builder) => builder.AddSerilog())
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });

我添加到Startup.cs

public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterType<QuartzWrapper>().As<IQuartzWrapper>().SingleInstance();
builder.Register(provider => new JobFactory(provider)).As<IJobFactory>().InstancePerDependency();
builder.RegisterType<JobClass>().As<IJob>().InstancePerDependency();

}

我使用了下一个包:

  1. Autofac-版本="5.1.2">
  2. Autofac.Extensions.DependencyInjection-版本="6.0.0">

您需要尝试并检查它在没有模块的情况下是如何工作的,请更改

builder.RegisterModule<BaseModule>();

builder.RegisterType<Config>().As<IConfig>().SingleInstance();

最新更新