-
-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Request for comments #1
Comments
Interesting to have a light weight abstraction for using the DI. I think ConfigureServices should be called as part of the constructor or on first invoke so that you aren't setting up the DI for every Lambda invocation. Also a lot of the logic in RequestResponseFunction's FunctionHandlerAsync seems like what you do inside ConfigureServices. ConfigureExecution seems oddly specific for setting up the logging factory. What is the full intent of that override. You might want a default implementation of Configure(IConfigurationBuilder builder) which pulls in the environment variables and appsettings.json as optional. That would reduce what users have to implement. I do like where you are going with this. |
Thank you for your feedback. I agree with your post although I have some thoughts about few bullets. First of all, I already had moved the call to When it comes to offer a default implementation, both I'm thinking of something like protected FunctionTemplate()
{
...
var loggerFactory = ServiceProvider.GetRequiredService<ILoggerFactory>();
ConfigureLogging(loggerFactory);
Logger = loggerFactory.CreateLogger("Function");
}
protected virtual void ConfigureLogging(ILoggerFactory loggerFactory)
{
loggerFactory.AddLambdaLogger(new LambdaLoggerOptions
{
IncludeCategory = true,
IncludeLogLevel = true,
IncludeNewline = true
});
} versus something like protected FunctionTemplate()
{
...
var loggerFactory = ServiceProvider.GetRequiredService<ILoggerFactory>();
loggerFactory.AddLambdaLogger(new LambdaLoggerOptions
{
IncludeCategory = true,
IncludeLogLevel = true,
IncludeNewline = true
});
ConfigureLogging(loggerFactory);
Logger = loggerFactory.CreateLogger("Function");
}
protected virtual void ConfigureLogging(ILoggerFactory loggerFactory) { } In the first case, the end user can still opt-out from what I think is the default setup (but it will still have the dependencies to, say, the LambdaLogger, Configuration.EnvironmentVariables, Configuration.Json and so on...). To summarize there are three options:
When it comes to Last but not least, I can't find a way to avoid passing all the needed types when registering the handler (cfr. protected void RegisterHandler<THandler>(IServiceCollection services)
where THandler : class, IRequestResponseHandler<TInput, TOutput>
{
services.AddRequestResponseHandler<THandler, TInput, TOutput>();
} to be used like RegisterHandler<UpperCaseHandler>(services); But this would break the convention of using extension methods. |
@normj sorry my total n00bness in GitHub. Do I need to tag you to notify you of a comment? I hope this doesn't look too rude :P |
Hey @Kralizek , thanks for creating this template. It's a good source for getting an idea on how to create a DI-Pipeline in lambda functions with less overhead than provided by As I am quite new to the topic and only have experience with Azure, I have some "noob"-questions ;) How exactly does this fit into the Lifecycle of lambda functions? The constructor gets called once on function init and the DI pipeline stays existent until the function runtime gets recycled, right? Do you see any option to share the same DI pipeline for multiple functions? This is what we did for our Azure functions and I think it would be more reasonable regarding resource pooling, memory usage, etc. As far as I understand Lambda functions right now each single function (or to name it differently, each "trigger event") has its own function runtime thus sharing resources is not possible. So if I want to leverage a shared setup I would do so by using inheritance, but it in fact would set up my dependency pipeline once per function implementation. Did you do any comparison on your approach with using Did you try out your template in practice and can share any experiences with it? Sorry if my thoughts are a bit unsorted, I am currently brainstorming what would be the best approach to rebuild our application with AWS lambda. I am 100% sure we need dependency injection, I am just not sure about the pros and cons between the 2 approaches I described above. |
This template tries to fit into the normal function lifecycle as much as possible:
Please let me know if you have more questions! |
Thanks for the fast response, I'll try it out during the next couple of days and will report back if there are any more questions or ideas for improvement. |
@normj what do you think? I put it down in a couple of hours, it can obviously be improved.
The idea is having a well-structured template so that developers know what to add where. Also, it should enforce best-practices like DI.
The text was updated successfully, but these errors were encountered: