Framework-level dependency injection with ASP.NET Core
Open Source Your Knowledge, Become a Contributor
Technology knowledge has to be shared and made accessible for free. Join the movement.
Dependency injection in ASP.NET Core
This example shows how framework-level dependency injection works in ASP.NET Core. It's simple but powerful enough to get most of dependency injection stuff done. Framework-level dependency injection supports the following scopes:
- Singleton - always return the same instance
- Transient - return new instance every time
- Scoped - return same instance in current (request) scope
Let's suppose we have two artifacts we want to be available through dependency injection:
- PageContext - custom request context
- Settings - global application settings
Both of these are very simple classes. PageContext class provides layout page with current page title to use in title tag.
public class Settings
{
public string SiteName;
public string ConnectionString;
}
public class PageContext
{
private readonly Settings _settings;
public PageContext(Settings settings)
{
_settings = settings;
}
public string PageTitle;
public string FullTitle
{
get
{
var title = (PageTitle ?? "").Trim();
if(!string.IsNullOrWhiteSpace(title) &&
!string.IsNullOrWhiteSpace(_settings.SiteName))
{
title += " | ";
}
title += _settings.SiteName.Trim();
return title;
}
}
}
Registering dependencies
Before using these classes in UI building blocks we need to register these classes when application starts. This is done in ConfigureServices() method of Startup class.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
var settings = new Settings();
settings.SiteName = Configuration["SiteName"];
services.AddSingleton(settings);
services.AddScoped<PageContext>();
}
Now it's possible to inject these classes to controllers and other UI components that support dependency-injection.
Injecting instances to controller
Let's assign titles to pages through PageContext class in Home controller.
public class HomeController : Controller
{
private readonly PageContext _pageContext;
public HomeController(PageContext pageContext)
{
_pageContext = pageContext;
}
public IActionResult Index()
{
_pageContext.PageTitle = "";
return View();
}
public IActionResult About()
{
_pageContext.PageTitle = "About";
return View();
}
public IActionResult Error()
{
_pageContext.PageTitle = "Error";
return View();
}
}
Assigning page titles this way is good as we don't have to use ViewData and it is easier for us to support multi-lingual applications.
Injecting instances to views
Now controller actions assign page title and it's time to make title available in layout page. I added title also near page content area so it is easy to see also in tech.io environment. To get page context to layout page I used view injection (the first line in the following code fragment).
@inject PageContext pageContext
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@pageContext.FullTitle</title>
<environment names="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment names="Staging,Production">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
</head>
...
</html>
Demo
We are done with page context now and it's time to try it out. The following live demo shows how page titles work. Click on menu items and see how page title changes in top of content area.
Reference materials
- Dependency injection in ASP.NET 5 (Gunnar Peipman)
- ASP.NET Core: Using view injection (Gunnar Peipman)