I've created an empty AWS Lambda project with .net CORE :
Which basically all it yields is a .net core empty lambda function project :
But as it is now - it doesn't support Injection (DI) , since there is no startup
file etc ...So basically it is ia .net core project without all its benefits.
However , Tony wrote about it:
Add .NET Core DI and Config Goodness to AWS Lambda Functions
" :
Basically what he did is to manually make the project support DI.
So I've created a ConfigurationService
class :
ConfigureServices.cs
public interface IConfigurationService
{
IConfiguration GetConfiguration();
}
public class ConfigurationService : IConfigurationService
{
public IConfiguration GetConfiguration()
{
return new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
}
}
And then used it in the code , as in a regular way .
So here is the same function as above returning a key from appSettigs , PLUS (!!!) Dependency Injection:
Function.cs
public class Function
{
public Function()
{
/*MANUALLY MAKING OUR PROJECT TO SUPPORT DI*/
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
var serviceProvider = serviceCollection.BuildServiceProvider();
ConfigService = serviceProvider.GetService<IConfigurationService>();
}
public IConfigurationService ConfigService { get; }
private void ConfigureServices(IServiceCollection serviceCollection)
{
serviceCollection.AddOptions();
serviceCollection.AddTransient<IConfigurationService, ConfigurationService>();
}
public string FunctionHandler(string input, ILambdaContext context)
{
var res = ConfigService.GetConfiguration()["Message"];
return res;
}
}
It does work :
(Here is the appsetting.json file BTW) :
appsettings.json
{
"Message": "Hello"
}
It also work when I Inject IConfigurationService
to other class'es constructor.
So where is the problem?
I want to use the type safe access to the appsettings.json using IOptions
.
— So I've created a corresponding file:
AppSettings.cs
public class AppSettings
{
public string Message { get; set; }
}
And now I need to configure
it , but look what happens:
It first invokes the ConfigureServices
method in line #16 , then It Configure
the AppSettings
at line #27 , and then it crashes(!) at line #27 becuase ConfigService
is null
.
Why is it null ? Because it is only assigned in line #18
Question
What should I do in order for the code to support Configure<Appsettings>
?
You do not really need IOptions
in this scenario and can configure the dependencies as needed
For example review the following
public class Function {
public static Func<IServiceProvider> ConfigureServices = () => {
var serviceCollection = new ServiceCollection();
serviceCollection.AddOptions(); //OPTIONAL
//...add additional services as needed
//building configuration
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
//Get strongly typed setting from appsettings binding to object graph
var settings = configuration.Get<AppSettings>();
// adding to service collection so that it can be resolved/injected as needed.
serviceCollection.AddSingleton(settings);
return serviceCollection.BuildServiceProvider();
};
static IServiceProvider services;
static Function() { //Static ctor invokes once.
services = ConfigureServices();
}
public string FunctionHandler(string input, ILambdaContext context) {
//...
var settings = services.GetRequiredService<AppSettings>();
var message = settings.Message;
return message;
}
}
A one time setup of static service provider is configured with the desired settings added to the provider as a strongly typed model which can be resolved and injected as needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With