带有 .Net 核心的 AWS Lambda - 为 IOptions 启用注入?

Roy*_*mir 8 c# amazon-web-services .net-core aws-lambda

我用 .net CORE 创建了一个空的 AWS Lambda 项目:

在此处输入图片说明

基本上它产生的是一个 .net 核心空 lambda 函数项目:

在此处输入图片说明

但就像现在一样 - 它不支持注入(DI),因为没有startup文件等......所以基本上它是 ia .net 核心项目,没有它的所有好处。

然而,托尼写道: Add .NET Core DI and Config Goodness to AWS Lambda Functions

基本上他所做的就是手动让项目支持DI。

所以我创建了一个ConfigurationService类:

配置服务.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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后以常规方式在代码中使用它。

所以这里是与上面相同的函数从 appSettigs 返回一个键,PLUS (!!!) 依赖注入:

函数.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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

它确实有效:

在此处输入图片说明

(顺便说一下,这是 appsetting.json 文件):

appsettings.json

{
    "Message": "Hello"
}
Run Code Online (Sandbox Code Playgroud)

当我注入IConfigurationService其他类的构造函数时,它也可以工作 。

那么问题出在哪里呢?

我想使用类型安全访问 appsettings.json IOptions
— 所以我创建了一个相应的文件:

应用设置.cs

 public class AppSettings
    {
        public string Message  { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

现在我需要configure它,但看看会发生什么:

在此处输入图片说明

它首先调用ConfigureServices在线路#16的方法,然后,它ConfigureAppSettings在线路#27,然后它崩溃(!)在线路#27监守ConfigServicenull。为什么它是 null ?因为它只在第 18 行赋值

我应该怎么做才能让代码支持Configure<Appsettings>

Nko*_*osi 7

IOptions在这种情况下你并不真正需要,可以根据需要配置依赖项

例如查看以下内容

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

静态服务提供者的一次性设置配置了所需的设置,作为强类型模型添加到提供者中,可以根据需要解析和注入。