Start using Dependency Injection with ASP.NET Core
November 17, 2016 · 3 minute read
ASP.NET Core ships with a built-in Dependency Injection Framework.
DI frameworks give you a way to set up all your dependencies in one place. You can then use these dependencies anywhere in your web application.
The common approach is to inject them via constructors.
For example, if you create an IUserStore interface which has methods for retrieving users, you can bring this into a controller like so.
[Route("api/[controller]")]
public class UserController : Controller
{
private IUserStore _userStore;
public UserController(IUserStore userStore)
{
_userStore = userStore;
}
[HttpGet("[action]")]
public IActionResult Test()
{
return Ok("worked");
}
}
The DI framework takes over the job of providing an instance of IUserStore
when the controller’s constructor is invoked. In the case of controller constructors this usually happens per web request.
All well and good but if you try to hit http://yourapp/api/user/test
you’ll see an error.
The DI framework has absolutely no idea how to resolve the IUserStore
dependency because we haven’t told it what to do.
Manual Configuration
You can manually configure the DI framework and tell it exactly which class to use when.
For example, you could explicitly tell the ASP.NET Core DI Framework to return an instance of InMemoryUserStore
when attempting to resolve the IUserStore
.
Modify the ConfigureServices
method in Startup.cs.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<IUserStore, InMemoryUserStore>();
}
AddSingleton
instructs the Core DI Framework to instantiate one instance of InMemoryUserStore
when it’s first requested, then use the same instance every time anything tries to use IUserStore
.
Singleton is one of several lifetimes you can choose for your dependencies. The other common one is Transient where a new instance of the service is created every time it’s requested.
For a full list (and explanation) see the official docs.
Singleton suits us for keeping some test data in memory because it means it will be preserved across multiple requests.
Here’s an simple implementation.
public interface IUserStore
{
void CreateUser(string name);
IList<string> ListAll();
}
public class InMemoryUserStore : IUserStore
{
IList<string> _users = new List<string>();
public void CreateUser(string name)
{
_users.Add(name);
}
public IList<string> ListAll()
{
return _users;
}
}
Testing the Singleton
To prove this actually works (and that the data is held between requests) we can update our test controller and give it a spin.
[Route("api/[controller]")]
public class UserController : Controller
{
private IUserStore _userStore;
public UserController(IUserStore userStore)
{
_userStore = userStore;
}
[HttpGet("[action]")]
public IActionResult Test()
{
return Ok("worked");
}
[HttpGet()]
public IList<string> List()
{
return _userStore.ListAll();
}
[HttpPost()]
public IActionResult Create(string name)
{
_userStore.CreateUser(name);
return Ok("User created");
}
}
Now if we use Postman to make a post to our controller we expect users to be added to the shared in-memory list inside InMemoryUserStore
.
And here’s our extremely exciting list of users having used postman to create a few with different names.
In Summary
Using DI frameworks provides a clean separation of concerns where the construction and lifetime of your services are managed separately from your core business logic, freeing you up to bring your services in wherever you need to, simply by passing them into the constructor.
You don’t have to stick with Microsoft’s DI Framework. There are a number of other well-established DI frameworks which play nicely with .NET Core and the good news is, once you’ve got your controllers set up with dependencies (like our example above), switching DI Frameworks is relatively painless and can be done without changing any of your business logic or controller code.
photo credit: adafruit MCP23017 – i2c 16 input/output port expander via photopin (license)
All posts in the
ASP.NET Core from scratch using the command line series.
- Your first .NET Core web application using just the command line (in ten minutes or less)
- How to add MVC to your ASP.NET Core web application
- Compile your changes on the fly with .NET Core Watch
- The basics of publishing your .NET Core web app
- How to serve static files for your Single Page Application from .NET Core
- Troubleshoot your ASP.NET Core web app using logging
- How to log different levels of information in your ASP.NET Core app
- Add Web API to your .NET Core application
- Start using Dependency Injection with ASP.NET Core