This might be a "stupid" question but I'm kind of lost, I'm trying to implement Autofac into a working .NET Core 3.1 Console Application but can't seem to get some things to work.
I have a class named Config.cs that are used at multiple places the console application so I'd like to keep that file so as to not rewrite this implementation.
Here is that file
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];
}
This is first used in Functions.cs
in a 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)
{
...
}
}
But when I start the console application an error is thrown
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:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\DefaultJobActivator.cs:line 37
at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstance[T](IFunctionInstanceEx functionInstance) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\DefaultJobActivator.cs:line 32
at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory`1.<>c__DisplayClass1_1.<.ctor>b__0(IFunctionInstanceEx i) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\ActivatorInstanceFactory.cs:line 20
at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory`1.Create(IFunctionInstanceEx functionInstance) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\ActivatorInstanceFactory.cs:line 26
at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.CreateInstance(IFunctionInstanceEx functionInstance) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 44
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ParameterHelper.Initialize() in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 846
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsyncCore(IFunctionInstanceEx functionInstance, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 117
This injection works without Autofac, but I'm "forced" to implement it since Autofac is used in every other project where I'm working.
Here is the Program.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();
}
}
What am I doing wrong, I'm sure there is something missing or that I did not understand correctly?
It is my sample for ASP .Net core 3.1
in Program.cs I changed
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>(); });
and I added to 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();
}
and I used the next packages: