Reputation: 105
I want to create an ASP.Net Core web service which will select rows from one SQL Server database and insert them into X SQL server database(s). All databases have the same structure (same model).
I don't want to inject DbContext because I don't know how many context I will have to use and it will be difficult to maintain.
Is it possible to manually create a DbContext in a controller or a manager like :
MyContextClass dbContext = new MyContextClass("myConnectionString");
Thank you
Upvotes: 4
Views: 5680
Reputation: 5740
Yes, it is possible to just create a new DbContext
.
However when using DI, you should write and inject something like a DbContextFactory
class that you can use to create a new context and that itself gets the DbContextOptions
from your configuration.
public class ContextFactory<TContext>
where TContext : DbContext
{
private readonly Func<TContext> _createContext;
public ContextFactory(Func<TContext> createContext)
{
_createContext = createContext ?? throw new ArgumentNullException(nameof(createContext));
}
TContext CreateForRead()
{
var context = Create();
context.ChangeTracker.AutoDetectChangesEnabled = false;
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
return context;
}
TContext CreateForWrite() => Create();
private TContext Create()
{
var context = _createContext();
if (context == null)
throw new NullReferenceException($"{nameof(_createContext)} must not return null.");
return context;
}
}
For easier use, create an extension class:
public static class ServiceCollectionDataExtensions
{
public static void AddDatabase<TDbContext>(this IServiceCollection services, string connectionString)
where TDbContext : DbContext
{
if (services == null)
throw new ArgumentNullException(nameof(services));
if (string.IsNullOrEmpty(connectionString))
throw new ArgumentNullException(nameof(connectionString));
services.AddDbContext<TDbContext>(c => c.UseSqlServer(connectionString), ServiceLifetime.Transient);
services.AddScoped(provider => new ContextFactory<TDbContext>(() => ActivatorUtilities.CreateInstance<TDbContext>(provider, provider.GetRequiredService<DbContextOptions<TDbContext>>())));
}
}
And then inside your public void ConfigureServices(IServiceCollection services)
add your connection string from your configuration:
services.AddDatabase<MyDbContext>(Configuration.GetConnectionString("MyDatabase"));
Upvotes: 2