0

.net core webapi application with entityframeworkcore. Trying to figure out how to pass an additional connection string into the data access library class in addition to the dbcontext. See ** dbcontext ** below is what I want to do.

startup.cs

       var SqlConnection = Configuration.GetConnectionString("SQLConnection");  
       var BlobConnection = Configuration.GetConnectionString("BlobConnection");

        services.AddEntityFramework()
                .AddEntityFrameworkSqlServer()
                .AddDbContext<VISTrackingContext>(options => options.UseSqlServer(SqlConnection, 
                sqlServerOptionsAction: sqlOptions =>
                {
                    sqlOptions.EnableRetryOnFailure(maxRetryCount: 5,
                    maxRetryDelay: TimeSpan.FromSeconds(5),
                    errorNumbersToAdd: null);
                }));

        services.AddScoped<IDataManager>(c => new DataManager(**_dbcontext**, BlobConnection));

        public FileController(IDataManager manager)
        {
            _datamanager = manager;
        }

        public DataManager(VISTrackingContext dbcontext, string blobconnection)
        {
            _dbcontext = dbcontext;
            _blobconnection = blobconnectionstring;
        }

Can this be done? Or is there another way to inject an additional connection string through the context object itself? I see lots of comments and options on doing this but none of the approaches deal with both the context and the connection string being passed to the repository object.

Tseng
  • 61,549
  • 15
  • 193
  • 205
user2503078
  • 737
  • 1
  • 8
  • 24

2 Answers2

1

You could store those connection strings in an object, and inject it to DataManager.

For example,

public class Startup
{
   public void ConfigureServices(IServiceCollection services)
   {
      ...
      services.AddSingleton(provider => new DataSettings(
         Configuration.GetConnectionString("SQLConnection"), 
         Configuration.GetConnectionString("BlobConnection")));

      services.AddScoped<IDataManager, DataManager>();
      ...
   }
}

public class DataSettings
{
    public DataSettings(string sqlConnection, string blobConnection)
    {
        SQLConnection = sqlConnection;
        BlobConnection = blobConnection;
    }

    public string SQLConnection { get; }

    public string BlobConnection { get; }
}

public DataManager(VISTrackingContext dbcontext, DataSettings dataSettings)
{
   _dbcontext = dbcontext;
   _blobconnection = dataSettings.BlobConnection;
}
Win
  • 61,100
  • 13
  • 102
  • 181
  • This looks great, but, how does this work? What links the datamanager in addscoped to the AddSIngleton(... class above it? – user2503078 Jun 28 '17 at 00:04
  • Inversion of Control (IoC) container should automatically resolve both dependencies - `VISTrackingContext` and `DataSettings` for `DataManager` at runtime. It is a beauty of using IoC container. – Win Jun 28 '17 at 00:16
0

Alternatively to @Win's answer, a more generic approach:

public class ConnectionStrings : Dictionary<string,string> { }

Startup.cs

services.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));
service.AddScoped<IDataManager,DataManager>();

// or
services.AddScoped<IDataManager>(c => new DataManager(
    c.GetRequiredService<YourDbContext>(),
    c.GetRequiredService<ConnectionStrings>()["BlobConnection"])
);

Service

public DataManager(VISTrackingContext dbcontext, ConnectionStrings connectionStrings)
Tseng
  • 61,549
  • 15
  • 193
  • 205