(CORE) CORE (2022)

Asp Net Core DI container - services, service instances, service parameters list and service parameters value, service resolver for services with the same type.

1. Services and service instances.

First main future for working with DI container is understanding the list of services and what is exactly services, and what is interface only and what is options. This code realize described functions.


   1:          Dim I As Integer = 0
   2:          Builder.Services.OrderBy(Function(Z) Z.Lifetime.ToString).ThenBy(Function(Z) Z.ServiceType.ToString).Distinct.ToList.ForEach(Sub(X)
   3:                                                                                                                                           I = I + 1
   4:                                                                                                                                           Dim ST As Type = X.ImplementationType
   5:                                                                                                                                           If ST IsNot Nothing Then
   6:                                                                                                                                               Dim ServiceInstance = Nothing
   7:                                                                                                                                               Try
   8:                                                                                                                                                   ServiceInstance = App.Services.GetRequiredService(ST)
   9:                                                                                                                                               Catch ex As System.InvalidOperationException
  10:                                                                                                                                               End Try
  11:                                                                                                                                               Debug.WriteLine($"{I}. {X.Lifetime} : {IIf(ServiceInstance IsNot Nothing, "HasInstance", "           ")} : {X.ServiceType}")
  12:                                                                                                                                           End If
  13:                                                                                                                                       End Sub)

Result of this code looks as



2. Service parameters list.

As you can see in previous point, most of type in DI container is Options or Interfaces. Options for configuring service is most important part, because it set rules what exactly services doing. To receive list of options I use this code:


   1:          Dim OptionTypeList = Builder.Services.Where(Function(X) X.ServiceType.IsGenericType).Select(Function(X) X.ServiceType.GetGenericArguments()(0)).Distinct.ToList
   2:          OptionTypeList.
   3:              Where(Function(X) X.FullName = "Microsoft.AspNetCore.Mvc.RazorPages.RazorPagesOptions").
   4:              ToList.ForEach(Sub(OneOptionType)
   5:                                 Debug.Print($"{OneOptionType.FullName}")
   6:                                 For J As Integer = 0 To OneOptionType.GetProperties.Count - 1
   7:                                     Dim Prop As Reflection.PropertyInfo = DirectCast(OneOptionType, System.Reflection.TypeInfo).DeclaredProperties(J)
   8:                                     If Prop IsNot Nothing Then
   9:                                         Debug.Print($"{J}. {Prop.Name} : Of {Prop.PropertyType.Name}")
  10:                                     Else
  11:                                         Debug.Print($"No public property")
  12:                                     End If
  13:                                 Next
  14:                                 Debug.Print("")
  15:                             End Sub)

This is list of options.



3. Service parameters Value.

To receive options value we need to inject configured services to Home/Index.


   1:  Imports Microsoft.AspNetCore.Mvc
   2:  Imports System.Diagnostics
   3:  Imports FrontEndData.Models
   4:  Imports Microsoft.Extensions.Logging
   5:  Imports Microsoft.AspNetCore.Http
   6:  Imports Microsoft.AspNetCore
   7:  Imports Microsoft.Extensions.Options
   8:  Imports Microsoft.AspNetCore.Mvc.ApplicationModels
   9:  Imports Newtonsoft.Json
  10:   
  11:  Namespace Controllers
  12:      Public Class HomeController
  13:          Inherits Controller
  14:   
  15:          Private ReadOnly _logger As ILogger(Of HomeController)
  16:          Private ReadOnly _Context As IHttpContextAccessor
  17:   
  18:          Private ReadOnly _RazorPagesOptions As RazorPages.RazorPagesOptions
  19:          Private ReadOnly _RazorViewEngineOptions As Razor.RazorViewEngineOptions
  20:          Private ReadOnly _MvcViewOptions As Mvc.MvcViewOptions
  21:          Private ReadOnly _IdentityOptions As Identity.IdentityOptions
  22:          Private ReadOnly _MvcOptions As Mvc.MvcOptions
  23:          Private ReadOnly _CookieAuthenticationOptions As Authentication.Cookies.CookieAuthenticationOptions
  24:          Private ReadOnly _AuthenticationOptions As Authentication.AuthenticationOptions
  25:          Private ReadOnly _RouteOptions As Routing.RouteOptions
  26:          Private ReadOnly _HostOptions As Microsoft.Extensions.Hosting.HostOptions
  27:          Private ReadOnly _KestrelServerOptions As Server.Kestrel.Core.KestrelServerOptions
  28:          Private ReadOnly _HostFilteringOptions As HostFiltering.HostFilteringOptions
  29:          Private ReadOnly _ApiBehaviorOptions As Mvc.ApiBehaviorOptions
  30:          Private ReadOnly _AntiforgeryOptions As Antiforgery.AntiforgeryOptions
  31:   
  32:          Public Sub New(ByVal logger As ILogger(Of HomeController), Context As IHttpContextAccessor,
  33:                         RazorPagesOptions As IOptions(Of RazorPages.RazorPagesOptions),
  34:                         RazorViewEngineOptions As IOptions(Of Razor.RazorViewEngineOptions),
  35:                         MvcViewOptions As IOptions(Of Mvc.MvcViewOptions),
  36:                         IdentityOptions As IOptions(Of Identity.IdentityOptions),
  37:                         MvcOptions As IOptions(Of Mvc.MvcOptions),
  38:                         CookieAuthenticationOptions As IOptions(Of Authentication.Cookies.CookieAuthenticationOptions),
  39:                         AuthenticationOptions As IOptions(Of Authentication.AuthenticationOptions),
  40:                         RouteOptions As IOptions(Of Routing.RouteOptions),
  41:                         HostOptions As IOptions(Of Microsoft.Extensions.Hosting.HostOptions),
  42:                         KestrelServerOptions As IOptions(Of Server.Kestrel.Core.KestrelServerOptions),
  43:                         HostFilteringOptions As IOptions(Of HostFiltering.HostFilteringOptions),
  44:                         ApiBehaviorOptions As IOptions(Of Mvc.ApiBehaviorOptions),
  45:                         AntiforgeryOptions As IOptions(Of Antiforgery.AntiforgeryOptions))
  46:   
  47:              _logger = logger
  48:              _Context = Context
  49:   
  50:              _RazorPagesOptions = RazorPagesOptions.Value
  51:              _RazorViewEngineOptions = RazorViewEngineOptions.Value
  52:              _MvcViewOptions = MvcViewOptions.Value
  53:              _IdentityOptions = IdentityOptions.Value
  54:              _MvcOptions = MvcOptions.Value
  55:              _CookieAuthenticationOptions = CookieAuthenticationOptions.Value
  56:              _AuthenticationOptions = AuthenticationOptions.Value
  57:              _RouteOptions = RouteOptions.Value
  58:              _HostOptions = HostOptions.Value
  59:              _KestrelServerOptions = KestrelServerOptions.Value
  60:              _HostFilteringOptions = HostFilteringOptions.Value
  61:              _ApiBehaviorOptions = ApiBehaviorOptions.Value
  62:              _AntiforgeryOptions = AntiforgeryOptions.Value
  63:              '
  64:              Debug.Print($"RazorViewEngineOptions : {JsonConvert.SerializeObject(_RazorViewEngineOptions, formatting:=Formatting.Indented)}")
  65:              Debug.Print($"IdentityOptions : {JsonConvert.SerializeObject(_IdentityOptions, formatting:=Formatting.Indented)}")
  66:              Debug.Print($"AuthenticationOptions : {JsonConvert.SerializeObject(_AuthenticationOptions, formatting:=Formatting.Indented)}")
  67:              Debug.Print($"RouteOptions : {JsonConvert.SerializeObject(_RouteOptions, formatting:=Formatting.Indented)}")
  68:              Debug.Print($"HostOptions : {JsonConvert.SerializeObject(_HostOptions, formatting:=Formatting.Indented)}")
  69:              Debug.Print($"HostFilteringOptions : {JsonConvert.SerializeObject(_HostFilteringOptions, formatting:=Formatting.Indented)}")
  70:              Debug.Print($"AntiforgeryOptions : {JsonConvert.SerializeObject(_AntiforgeryOptions, formatting:=Formatting.Indented)}")
  71:              'Debug.Print($"RazorPagesOptions : {JsonConvert.SerializeObject(_RazorPagesOptions)}") 'No public member
  72:              'Debug.Print($"MvcViewOptions : {JsonConvert.SerializeObject(_MvcViewOptions)}") 'No public member
  73:              'Debug.Print($"MvcOptions : {JsonConvert.SerializeObject(_MvcOptions)}") 'No public member
  74:              'Debug.Print($"ApiBehaviorOptions : {JsonConvert.SerializeObject(_ApiBehaviorOptions)}") 'No public member
  75:              'Debug.Print($"CookieAuthenticationOptions : {JsonConvert.SerializeObject(_CookieAuthenticationOptions)}")  'Loop
  76:              'Debug.Print($"KestrelServerOptions : {JsonConvert.SerializeObject(_KestrelServerOptions})}")   'Loop
  77:          End Sub

Unfortunately most options is private and we can see it only on Visual Studio Debugger, other options is impossible to print because it contains loop link to himself. This is example of options we can print.



Other opportunity is directly adding handler to route table, inject services and call this handler without controller.


  272:          App.MapGet("/", Function(loggerFactory As ILoggerFactory, Context As IHttpContextAccessor,
  273:                         RazorPagesOptions As IOptions(Of RazorPages.RazorPagesOptions),
  274:                         RazorViewEngineOptions As IOptions(Of Razor.RazorViewEngineOptions),
  275:                         MvcViewOptions As IOptions(Of Mvc.MvcViewOptions),
  276:                         IdentityOptions As IOptions(Of Identity.IdentityOptions),
  277:                         MvcOptions As IOptions(Of Mvc.MvcOptions),
  278:                         CookieAuthenticationOptions As IOptions(Of Authentication.Cookies.CookieAuthenticationOptions),
  279:                         AuthenticationOptions As IOptions(Of Authentication.AuthenticationOptions),
  280:                         RouteOptions As IOptions(Of Routing.RouteOptions),
  281:                         HostOptions As IOptions(Of Microsoft.Extensions.Hosting.HostOptions),
  282:                         KestrelServerOptions As IOptions(Of Server.Kestrel.Core.KestrelServerOptions),
  283:                         HostFilteringOptions As IOptions(Of HostFiltering.HostFilteringOptions),
  284:                         ApiBehaviorOptions As IOptions(Of Mvc.ApiBehaviorOptions),
  285:                         AntiforgeryOptions As IOptions(Of Antiforgery.AntiforgeryOptions))
  286:                              Dim Log = loggerFactory.CreateLogger("Options")
  287:                              Log.LogInformation($"RazorViewEngineOptions : {JsonConvert.SerializeObject(RazorViewEngineOptions, formatting:=Formatting.Indented)}")
  288:                              Log.LogInformation($"IdentityOptions : {JsonConvert.SerializeObject(IdentityOptions, formatting:=Formatting.Indented)}")
  289:                              Log.LogInformation($"AuthenticationOptions : {JsonConvert.SerializeObject(AuthenticationOptions, formatting:=Formatting.Indented)}")
  290:                              Log.LogInformation($"RouteOptions : {JsonConvert.SerializeObject(RouteOptions, formatting:=Formatting.Indented)}")
  291:                              Log.LogInformation($"HostOptions : {JsonConvert.SerializeObject(HostOptions, formatting:=Formatting.Indented)}")
  292:                              Log.LogInformation($"HostFilteringOptions : {JsonConvert.SerializeObject(HostFilteringOptions, formatting:=Formatting.Indented)}")
  293:                              Log.LogInformation($"AntiforgeryOptions : {JsonConvert.SerializeObject(AntiforgeryOptions, formatting:=Formatting.Indented)}")
  294:                              Return "Service options inspected."
  295:                          End Function)
  296:          App.Run()
  297:      End Sub
  298:  End Module


4. Change service options.

We can add parameters for services as delegate types or as separately types.


   1:          Builder.WebHost.ConfigureKestrel(Sub(KestrelServerOptions)
   2:                                               KestrelServerOptions.ListenLocalhost(5158)
   3:                                               KestrelServerOptions.ListenAnyIP(7168, Function(X) X.UseHttps)
   4:                                           End Sub)
   5:          Builder.Services.AddRazorPages(Sub(options As RazorPagesOptions)
   6:                                             options.RootDirectory = "/Pages"
   7:                                             options.Conventions.AuthorizeFolder("/Account/Manage")
   8:                                             options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout")
   9:                                         End Sub)
  10:          Builder.Services.ConfigureApplicationCookie(Sub(options)
  11:                                                          options.Cookie.HttpOnly = True
  12:                                                          options.Cookie.Expiration = TimeSpan.FromDays(5)
  13:                                                          options.LoginPath = "/Identity/Account/Login"
  14:                                                          options.LogoutPath = "/Identity/Account/Logout"
  15:                                                          options.AccessDeniedPath = "/Identity/Account/AccessDenied"
  16:                                                      End Sub)
  17:          Builder.Services.Configure(Of IdentityOptions)(Sub(options)
  18:                                                             'Password settings.
  19:                                                             options.Password.RequireDigit = True
  20:                                                             options.Password.RequireLowercase = True
  21:                                                             options.Password.RequireNonAlphanumeric = True
  22:                                                             options.Password.RequireUppercase = True
  23:                                                             options.Password.RequiredLength = 6
  24:                                                             options.Password.RequiredUniqueChars = 1
  25:                                                             'Lockout settings.
  26:                                                             options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5)
  27:                                                             options.Lockout.MaxFailedAccessAttempts = 5
  28:                                                             options.Lockout.AllowedForNewUsers = True
  29:                                                             'User settings.
  30:                                                             options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"
  31:                                                             options.User.RequireUniqueEmail = False
  32:                                                         End Sub)

5. Service resolver for services with the same type, for example.

Look please to this my post https://www.vb-net.com/CoreLinuxMiddlewareTest/Index.htm#ServiceResolver.



Comments ( )
<00>  <01>  <02>  <03>  <04>  <05>  <06>  <07>  <08>  <09>  <10>  <11>  <12>  <13>  <14>  <15>  <16>  <17>  <18>  <19>  <20>  <21>  <22>  <23
Link to this page: http://www.vb-net.com/DIContainerServices/Index.htm
<SITEMAP>  <MVC>  <ASP>  <NET>  <DATA>  <KIOSK>  <FLEX>  <SQL>  <NOTES>  <LINUX>  <MONO>  <FREEWARE>  <DOCS>  <ENG>  <CHAT ME>  <ABOUT ME>  < THANKS ME>