Framework-level dependency injection with ASP.NET Core

gpeipman
9,998 views

Open Source Your Knowledge, Become a Contributor

Technology knowledge has to be shared and made accessible for free. Join the movement.

Create Content

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.

Run demo

Reference materials

Open Source Your Knowledge: become a Contributor and help others learn. Create New Content