;

Dependency injection

Your startup.cs defines your dependencies used in your controllers, and is a wonderful way of accessing data, external services and other resources used in your app. There is one caveat though.

Service lifetime

Keep track of the lifetime of your services, especially when nesting different services into each other.

There are three types of lifetimes: Transient, Scoped and Singleton, Where the shortest of the three is the transient lifetime, a new instance is passed to the controller every time the constructor is called. For scoped services, it's usually explained with “one instance per web request”. Though it's more complicated than that, it's enough for this example. Singleton Services have the longest lifetime of a web application. They are supposed to live through the entire lifetime of the application.

This is example of a pretty simple service, IMemoryCache is a singleton and all services depending solely on IMemoryCache could also be singletons.

// startup.cs -> ConfigureServices()
services.AddMemoryCache();
services.AddSingleton<ICacheHandler>(factory => {
    var cache = factory.GetRequiredService<IMemoryCache>();
    return new CacheHandler(cache);
});

However, if your service depends on a scoped service, your service must also be scoped or a transient service.

// startup.cs -> ConfigureServices()
services.AddMemoryCache();
services.AddScoped<IMyService>(factory => {
    return new MyService(config)
});

services.AddScoped<ICacheHandler>(factory => {
    var cache = factory.GetRequiredService<IMemoryCache>();
    var myservice = factory.GetRequiredService<IMyService>();
    return new CacheHandler(cache, myservice);
});

You have a full article here Dependency injection in ASP.NET Core. And it should be your first read when beginning with asp.net core.

@inject in your views

It can be quite bugprone to pass data between views and partial views. Below is an example of a menu partial view.

@inject IAuthorizationHandler authorizationHandler
@inject IContentDataAdapter contentDataAdapter
@{
    var loginInfo = await authorizationHandler.GetUserLoginInfo(this.User);
    var articles = await contentDataAdapter.GetArticles(loginInfo.IsAdmin);
}