Hòa Nguyễn Coder
Posted on June 15, 2020
Setup Service in ASP.NET CORE 2.1, We need register Service in Startup.cs. When we build project, Service in Startup.cs class file, will be start
In project, we througth register much service, so need add service to Startup.cs file, when start
You can see it: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1#service-lifetimes-and-registration-options
- Transient : The object is always different. Every time we call it, it create a new object
- Scoped : Created once for each request, the objects have the same scope in a request and it uses the same instance in other calls in the same web request.
- Singleton : Singleton objects are the same for every object and every request. The service is created only once.
Okay, now create project.
Steps 1: In Visual Studio 2019, File->New, select Project
Steps 2: Select Create a new project
Steps 3: Select ASP.NET Core Web Application template
Steps 4: Enter name project, select Create
Steps 5: Select .NET Core, ASP.NET Core 2.1, Select Web Application (Model-View-Controller), after then click Create
If you create project complete, go to Models folder, create model Product.cs file
- Models/Product.cs
public class Product
{
public int idProduct { get; set; }
public string Title { get; set; }
public string UrlImage { get; set; }
public decimal Price { get; set; }
public string Detail { get; set; }
}
Create (Scoped, Singleton, Transient) folder
Transient
Go to Services/Transient directory, create two file(ITransient.cs,ItemTransientService.cs)
- Services/Transient/ITransient.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AddServiceASP_core21.Models;
namespace AddServiceASP_core21.Services.Transient
{
public interface ITransient
{
//return product
Product getProduct();
//return server count
int countService();
}
}
- Services/Transient/ItemTransientService.cs : Inherits from ITransient.cs, to build the methods defined in ITransient.cs
using AddServiceASP_core21.Models;
namespace AddServiceASP_core21.Services.Transient
{
public class ItemTransientService : ITransient
{
Product product;
int count=0;
public ItemTransientService()
{
product = new Product
{
idProduct = 1,
Title = "Test Transient:" + Guid.NewGuid(),
UrlImage = "Transient.jpg",
Price = 79000,
Detail = "Transient"
};
}
public Product getProduct()
{
count++;
return product;
}
public int countService()
{
return count;
}
}
}
After when we setup complete, now we need register it to Startup.cs file
Steps 1: using AddServiceASP_core21.Services.Transient;
Steps 2: Register using AddServiceASP_core21.Services.Transient; in ConfigureServices method
Okay, go to Controllers folder->add new ProductController.cs
using AddServiceASP_core21.Services.Transient;
namespace AddServiceASP_core21.Controllers
{
public class ProductController : Controller
{
/*Transient*/
private readonly ITransient _transient1;
private readonly ITransient _transient2;
public ProductController(ITransient transient1, ITransient transient2)
{
_transient1 = transient1;
_transient2 = transient2;
}
public IActionResult Index()
{
//Transient
ViewBag.data01 = _transient1.getProduct();
ViewBag.count01 = _transient1.countService();
ViewBag.data02 = _transient2.getProduct();
ViewBag.count02 = _transient2.countService();
return View();
}
}
}
- Views/Product/Index.cshtml:
@model IEnumerable<Product>
@{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
//Transient
var data01 = ViewBag.data01;
var data02 = ViewBag.data02;
}
<h2>Transient</h2>
<span>@data01.Title - [Price:@data01.Price] - CountServer:@ViewBag.count01</span>
<br />
<span>@data02.Title - [Price:@data02.Price] - CountServer:@ViewBag.count02</span>
In the figure above, we see ID always different, Server always create, so params Count always is 1
Singleton
- Services/Singleton/ISingleton.cs
using AddServiceASP_core21.Models;
namespace AddServiceASP_core21.Services.Singleton
{
public interface ISingleton
{
Product getProduct();
int countService();
}
}
- Services/Singleton/ItemSingletonService.cs
using AddServiceASP_core21.Models;
namespace AddServiceASP_core21.Services.Singleton
{
public class ItemSingletonService : ISingleton
{
Product product;
int count = 0;
public ItemSingletonService()
{
product = new Product
{
idProduct = 1,
Title = "Test Singleto:" + Guid.NewGuid(),
UrlImage = "Singleto.jpg",
Price = 79000,
Detail = "Singleto"
};
}
public Product getProduct()
{
count++;
return product;
}
public int countService()
{
return count;
}
}
}
Okay, we need register it to Startup.cs
services.AddSingleton(); in ConfigureServices method
- Controllers/ProductController.cs: modify the following below code
using AddServiceASP_core21.Services.Transient;
using AddServiceASP_core21.Services.Singleton;
namespace AddServiceASP_core21.Controllers
{
public class ProductController : Controller
{
/*Transient*/
private readonly ITransient _transient1;
private readonly ITransient _transient2;
/*SingletoService*/
private readonly ISingleton _singleton1;
private readonly ISingleton _singleton2;
public ProductController(ITransient transient1, ITransient transient2,ISingleton singleton1, ISingleton singleton2)
{
_transient1 = transient1;
_transient2 = transient2;
_singleton1 = singleton1;
_singleton2 = singleton2;
_scoped1 = scoped1;
_scoped2 = scoped2;
}
public IActionResult Index()
{
//Transient
ViewBag.data01 = _transient1.getProduct();
ViewBag.count01 = _transient1.countService();
ViewBag.data02 = _transient2.getProduct();
ViewBag.count02 = _transient2.countService();
//Singleto
ViewBag.data03 = _singleton1.getProduct();
ViewBag.count03 = _singleton1.countService();
ViewBag.data04 = _singleton2.getProduct();
ViewBag.count04 = _singleton2.countService();
return View();
}
}
}
- Views/Product/Index.cs
@model IEnumerable<Product>
@{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
//Transient
var data01 = ViewBag.data01;
var data02 = ViewBag.data02;
//Singleto
var data03 = ViewBag.data03;
var data04 = ViewBag.data04;
}
<h2>Transient</h2>
<span>@data01.Title - [Price:@data01.Price] - CountServer:@ViewBag.count01</span>
<br />
<span>@data02.Title - [Price:@data02.Price] - CountServer:@ViewBag.count02</span>
<p>----------------------------------------------</p>
<h2>Singleto</h2>
<span>@data03.Title - [Price:@data03.Price] - CountServer:@ViewBag.count03</span>
<br />
<span>@data04.Title - [Price:@data04.Price] - CountServer:@ViewBag.count04</span>
Demo Transient & Scoped:
You see the figure above, The Product object does not change the ID despite repeated refreshes, But the Count increases, that is, the Server only runs once, it stores the object and uses it again
Scoped
- Services/Scoped/IScoped.cs
using AddServiceASP_core21.Models;
namespace AddServiceASP_core21.Services.Scoped
{
public interface IScoped
{
Product getProduct();
int countService();
}
}
- Services/Scoped/ItemScopedService.cs
using AddServiceASP_core21.Models;
namespace AddServiceASP_core21.Services.Scoped
{
public class ItemScopedService : IScoped
{
Product product;
int count = 0;
public ItemScopedService()
{
product = new Product
{
idProduct = 1,
Title = "Test Scoped:" + Guid.NewGuid(),
UrlImage = "Scoped.jpg",
Price = 79000,
Detail = "Singleto"
};
}
public Product getProduct()
{
count++;
return product;
}
public int countService()
{
return count;
}
}
}
- Controllers/ProductController.cs
using AddServiceASP_core21.Models;
using AddServiceASP_core21.Services.Transient;
using AddServiceASP_core21.Services.Singleton;
using AddServiceASP_core21.Services.Scoped;
namespace AddServiceASP_core21.Controllers
{
public class ProductController : Controller
{
/*Transient*/
private readonly ITransient _transient1;
private readonly ITransient _transient2;
/*SingletoService*/
private readonly ISingleton _singleton1;
private readonly ISingleton _singleton2;
/*ScopedService*/
private readonly IScoped _scoped1;
private readonly IScoped _scoped2;
public ProductController(ITransient transient1, ITransient transient2,ISingleton singleton1, ISingleton singleton2, IScoped scoped1,IScoped scoped2)
{
_transient1 = transient1;
_transient2 = transient2;
_singleton1 = singleton1;
_singleton2 = singleton2;
_scoped1 = scoped1;
_scoped2 = scoped2;
}
public IActionResult Index()
{
//Transient
ViewBag.data01 = _transient1.getProduct();
ViewBag.count01 = _transient1.countService();
ViewBag.data02 = _transient2.getProduct();
ViewBag.count02 = _transient2.countService();
//Singleto
ViewBag.data03 = _singleton1.getProduct();
ViewBag.count03 = _singleton1.countService();
ViewBag.data04 = _singleton2.getProduct();
ViewBag.count04 = _singleton2.countService();
//Scoped
ViewBag.data05 = _scoped1.getProduct();
ViewBag.count05 = _scoped1.countService();
ViewBag.data06 = _scoped2.getProduct();
ViewBag.count06 = _scoped2.countService();
return View();
}
}
}
We need register Scode in Startup.cs file,
services.AddScoped();
- Startup.cs (full code)
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using AddServiceASP_core21.Services.Transient;
using AddServiceASP_core21.Services.Singleton;
using AddServiceASP_core21.Services.Scoped;
namespace AddServiceASP_core21
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
//Transient
services.AddTransient<ITransient, ItemTransientService>();
//Singleto
services.AddSingleton<ISingleton, ItemSingletonService>();
//Scoped
services.AddScoped<IScoped, ItemScopedService>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Product}/{action=Index}/{id?}");
});
}
}
}
- Views/Product/Index.cshtml
@model IEnumerable<Product>
@{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
//Transient
var data01 = ViewBag.data01;
var data02 = ViewBag.data02;
//Singleto
var data03 = ViewBag.data03;
var data04 = ViewBag.data04;
//Scoped
var data05 = ViewBag.data05;
var data06 = ViewBag.data06;
}
<h2>Transient</h2>
<span>@data01.Title - [Price:@data01.Price] - CountServer:@ViewBag.count01</span>
<br />
<span>@data02.Title - [Price:@data02.Price] - CountServer:@ViewBag.count02</span>
<p>----------------------------------------------</p>
<h2>Singleto</h2>
<span>@data03.Title - [Price:@data03.Price] - CountServer:@ViewBag.count03</span>
<br />
<span>@data04.Title - [Price:@data04.Price] - CountServer:@ViewBag.count04</span>
<p>----------------------------------------------</p>
<h2>Scoped</h2>
<span>@data05.Title - [Price:@data05.Price] - CountServer:@ViewBag.count05</span>
<br />
<span>@data06.Title - [Price:@data06.Price] - CountServer:@ViewBag.count06</span>
Demo Transient & Singleto & Scoped
We see Scoped on the image above, the ID does not change, it only changes when refreshing the page, and Count it always changes
It only creates a new request object once, so the ID doesn't change, and that's why its Count increased by 2.
Each time you request the page again, it will create a new object
Github:https://github.com/skipperhoa/add-services-aspcore
The Article:Add Service in ASP.NET Core 2.1
Posted on June 15, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.