0

I have a simple function generated by AWS Toolkit for Visual Studio, and I'm trying to set up DynamoDBContext with dependency injection. However whenever I try to fetch the IDynamoDBContext from the IServiceProvider, I'm getting a NullReferenceException with no useful information.

Can anyone help me understand what I'm missing?

public interface IMyDependency { }

public class MyDependency : IMyDependency { }

public class Function
{
    public Function()
    {
        var services = ConfigureServices();

        // OK
        var dependency = services.GetService<IMyDependency>();

        // NullReferenceException
        var db = services.GetService<IDynamoDBContext>();
    }

    private IServiceProvider ConfigureServices()
    {
        var services = new ServiceCollection();

        services.AddTransient<IMyDependency, MyDependency>();
        
        services.AddAWSService<IAmazonDynamoDB>();
        services.AddTransient<IDynamoDBContext, DynamoDBContext>();

        return services.BuildServiceProvider();
    }
}

My project file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
    <AWSProjectType>Lambda</AWSProjectType>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Amazon.Lambda.Core" Version="1.2.0" />
    <PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.1.0" />
    <PackageReference Include="Amazon.Lambda.SQSEvents" Version="1.2.0" />
    <PackageReference Include="AWSSDK.DynamoDBv2" Version="3.5.3.2" />
    <PackageReference Include="AWSSDK.Extensions.NETCore.Setup" Version="3.3.101" />
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.0" />
  </ItemGroup>
</Project>

Edit:

Stack trace from the exception that's thrown:

at Amazon.Extensions.NETCore.Setup.ClientFactory.CreateConfig(Type serviceInterfaceType, AWSOptions options) in D:\\JenkinsWorkspaces\\trebuchet-stage-release\\AWSDotNetPublic\\extensions\\src\\AWSSDK.Extensions.NETCore.Setup\\ClientFactory.cs:line 171
at Amazon.Extensions.NETCore.Setup.ClientFactory.CreateServiceClient(ILogger logger, Type serviceInterfaceType, AWSOptions options) in D:\\JenkinsWorkspaces\\trebuchet-stage-release\\AWSDotNetPublic\\extensions\\src\\AWSSDK.Extensions.NETCore.Setup\\ClientFactory.cs:line 89
at Amazon.Extensions.NETCore.Setup.ClientFactory.CreateServiceClient(IServiceProvider provider) in D:\\JenkinsWorkspaces\\trebuchet-stage-release\\AWSDotNetPublic\\extensions\\src\\AWSSDK.Extensions.NETCore.Setup\\ClientFactory.cs:line 75
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitDisposeCache(ServiceCallSite transientCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
at AWSLambda.Example.Function..ctor() in C:\\Source\\Git\\AWSLambda.Example\\AWSLambda.Example\\Function.cs:line 36
2
  • 1
    You say "no useful information", we say "post the stack trace". Commented Nov 19, 2020 at 12:40
  • @IanKemp Good call, I've included that in the description. Thanks Commented Nov 19, 2020 at 12:47

1 Answer 1

1

The problem was that I had to add the default AWS options.

I added the JSON configuration in appsettings:

  "AWS": {
    "Region": "eu-west-2"
  }

Build the configuration within the function constructor:

public Function()
{
   var config = ConfigureAppConfiguration();
   var services = ConfigureServices(config);

   // ...
}

private IConfiguration ConfigureAppConfiguration()
{
    return new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true)
        .AddEnvironmentVariables()
        .Build();
}

And updated the ConfigureServices method to add the AWS options:

private IServiceProvider ConfigureServices(IConfiguration config)
{
    var services = new ServiceCollection();

    services.AddTransient<IMyDependency, MyDependency>();

    services.AddDefaultAWSOptions(config.GetAWSOptions()); // <-- This was mssing
    services.AddAWSService<IAmazonDynamoDB>();
    services.AddTransient<IDynamoDBContext, DynamoDBContext>();

    return services.BuildServiceProvider();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.