What is Dependancy Injection?
The type of Dependency Injection ill be looking at today can be categorized as “Constructor Injection”. The idea is that we will inject the needed classes into the constructor, rather than creating or instantiating new objects, thus achieving loose coupling between objects.
Dependency Injection is setup in the ConfigureServices method of Startup.cs
This ConfigureServices method is responsible for setting the things that can be injected into our constructors.
In this example I will focus on setting up DB Contexts. To learn more about registering your own services check out Microsoft’s docs here.
Creating a New ASP.NET Core Web Application
When you create a new ASP.NET Core Web Application with Authentication your ConfigureServices method and appsetting.json are set up automatically for you. This is a good place to start. You will see that AddDBContext() is in ConfigureServices and the connection string is stored in appsettings.json. It should look something like this…
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); ................. } appsettings.json { "ConnectionStrings": { "DefaultConnection": "Server=XXXXXX,1433;Initial Catalog=XXXXXX;Persist Security Info=False;User ID=XXXXXXX;Password=XXXXXXX;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate= alse;Connection Timeout=30;", } }
This is great, and if it is a part of a new web application, then migrations is auto setup for you. But what if you have another database that you want to build a model for, set up its context, then inject into your controllers…
Injecting an existing DB and DB Context
If you ran the linked above “scaffold” command to create your model and context, you will see that the connection string is set in the OnConfiguring() method or you new context.If you ran the linked above “scaffold” command to create your model and context, you will see that the connection string is set in the OnConfiguring() method or you new context.
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { #warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. optionsBuilder.UseSqlServer(@"XXXXXt;Database=XXXXX;user id=XXXXX;password=XXXXX;"); }
Delete the entire above OnConfiguring() method. Replace it with a constructor for your context (below) and pass it the DB options that we will setup next, in our Startup.cs class
public SunstackContext(DbContextOptions<MyNewContext> options) : base(options) { //any changes to the context options can now be done here }
Next, we want to add the database’s connection string to appsettings.json
"ConnectionStrings": { "DefaultConnection": "Server=XXXXX,1433;Initial Catalog=XXXXX;Persist Security Info=False;User ID=XXXXXX;Password=XXXXXX;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;", "MyNewConnection": "XXXXXX,1433;Initial Catalog=XXXXX;Persist Security Info=False;User ID=XXXXX;Password=XXXXX;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" },
And then we hook up this DBContext to your services in ConfigureServices()
public void ConfigureServices(IServiceCollection services) { // Add User DB connection services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); //Add My New DB connection services.AddDbContext<MyNewContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyNewConnection") )); .......... }
At this point everything should build!!
We now have the new context setup and ready to inject into a controller. The last step is very easy, just add our new service to ANY controller’s constructor, here is simple example.
public class FileManagerController : Controller { MyNewContext _myNewContext; public FileManagerController(MyNewContext context) { _myNewContext = context; } }