Search code examples
c#mongodbkubernetes.net-coreautofac

.NET Core API is throwing Autofac.Core.DependencyResolutionException


I have an API and MongoDB that was hosted on Kubernetes (EKS on AWS specifically). While my API runs completely fine on my local and also Docker local, it was not on the Kubernetes cluster.

When I get the logs from kubernetes logs -f <pod-name>, I get below exceptions:

Unexpected generic exception occurred Autofac.Core.DependencyResolutionException: An exception was thrown while activating QueryService -> Database -> DbClient.
       ---> Autofac.Core.DependencyResolutionException: An exception was thrown while invoking the constructor 'Void .ctor(Microsoft.Extensions.Options.IOptions`1[DbOptions])' on type 'DbClient'.
       ---> System.ArgumentNullException: Value cannot be null. (Parameter 'connectionString')
         at MongoDB.Driver.Core.Misc.Ensure.IsNotNull[T](T value, String paramName)
         at MongoDB.Driver.Core.Configuration.ConnectionString..ctor(String connectionString, IDnsResolver dnsResolver)
         at MongoDB.Driver.Core.Configuration.ConnectionString..ctor(String connectionString)
         at MongoDB.Driver.MongoUrlBuilder.Parse(String url)
         at MongoDB.Driver.MongoUrlBuilder..ctor(String url)
         at MongoDB.Driver.MongoUrl..ctor(String url)
         at MongoDB.Driver.MongoClientSettings.FromConnectionString(String connectionString)
         at MongoDB.Driver.MongoClient..ctor(String connectionString)
         at Mongo.DbOperations..ctor(String connectionString, String dataBase, String collection) in /src/Mongo/DbOperations.cs:line 36
         at DbClient..ctor(IOptions`1 DbOptions) in /src/DbClient.cs:line 22
         at lambda_method(Closure , Object[] )
         at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()
         --- End of inner exception stack trace ---
         at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()
         at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
         at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget)
         --- End of inner exception stack trace ---
         at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters, Object& decoratorTarget)
         at Autofac.Core.Resolving.InstanceLookup.Execute()
         at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)
         at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest request)
         at Autofac.Features.LazyDependencies.LazyRegistrationSource.<>c__DisplayClass5_1`1.<CreateLazyRegistration>b__1()
         at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
         at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
         at System.Lazy`1.CreateValue()
         at Api.Controllers.MainController.<>c__DisplayClass4_0.<<ListLogicalDevicesAsync>b__0>d.MoveNext() in /src/Api/Controllers/Main/List.cs:line 40
      --- End of stack trace from previous location where exception was thrown ---
         at Api.Controllers.StandardController.ProcessExceptionsAsync(Func`1 action) in /src/Api/Controllers/StandardController.cs:line 64

The dependency injection should have no problem since I can run it locally without any trouble. So is it the connection string that I provided for MongoDB not working? Or is it really the dependency injection issue?

Below are my code for constructor in DbOperation.cs

public DbOperations(string connectionString, string dataBase, string collection)
    var mongoClient = new MongoClient(connectionString);
    var mongoDatabase = mongoClient.GetDatabase(dataBase);
     _collection = mongoDatabase.GetCollection<BsonDocument>(collection);
}

My DbClient.cs

internal class DbClient : DbOperations, IDbClient
{
    public DbClient(IOptions<DbOptions> dbOptions) : 
        base(dbOptions.Value.ConnectionString,dbOptions.Value.Database, dbOptions.Value.DeviceCollection)
    {
    }
}

My Startup.cs

//In ConfigureContainer() method
builder.RegisterType<DbClient>().As<IDbClient>();

//In ConfigureServices() method
services.Configure<DbOptions>(configuration.GetSection("MainDb"));

My DbOptions.cs

public class DbOptions
{
    public string ConnectionString { get; set; }
    public string Database { get; set; }
    public string DeviceCollection { get; set; }
}

My appsetting.json

  "MainDb": {
    "Database": "main",
    "DeviceCollection": "data"
  }

My appsetting.Dev.json

  "MainDb": {
    "ConnectionString": "mongodb://<service-name>.default.svc.cluster.local:27017"
  }

May I know is there anything that might gone wrong? Is it the MongoDB connection string? Or the dependency injection that could not get the connection string?

Thanks!


Solution

  • Based on the exception message and the stack trace, connectionString is null. Check your config -- it's missing in your non-dev config.