Generic Host, DI, Configuration and Logging
30.1 Generic Host in a VB Console App
Imports Microsoft.Extensions.Configuration
Imports Microsoft.Extensions.DependencyInjection
Imports Microsoft.Extensions.Hosting
Imports Microsoft.Extensions.Logging
Imports Microsoft.Extensions.Options
Public Class SmtpOptions
Public Property Host As String
Public Property Port As Integer = 25
Public Property From As String
End Class
Public Interface IEmailSender
Function SendAsync([to] As String, subject As String, body As String) As Task
End Interface
Public Class SmtpEmailSender
Implements IEmailSender
Private ReadOnly _options As SmtpOptions
Private ReadOnly _logger As ILogger(Of SmtpEmailSender)
Public Sub New(options As IOptions(Of SmtpOptions), logger As ILogger(Of SmtpEmailSender))
_options = options.Value
_logger = logger
End Sub
Public Function SendAsync([to] As String, subject As String, body As String) As Task Implements IEmailSender.SendAsync
_logger.LogInformation("Sending '{Subject}' to {To} via {Host}:{Port}", subject, [to], _options.Host, _options.Port)
Return Task.CompletedTask
End Function
End Class
Module Program
Sub Main(args As String())
Dim builder = Host.CreateApplic
…// appsettings.json
{
"Smtp": { "Host": "smtp.example.com", "Port": 587, "From": "noreply@example.com" },
"Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning" } },
"ConnectionStrings": { "Shop": "Server=(localdb)\\MSSQLLocalDB;Database=Shop;Trusted_Connection=True" }
}30.2 Dependency Injection Concepts
One instance for the app Configuration, caches, HttpClient factories One per scope (request/unit of work) DbContext, unit of work New every time Lightweight stateless services
Constructor injection is preferred. Avoid the service locator pattern. Don't inject scoped services into singletons (captive dependencies).
Create scopes manually in workers: Using scope = provider.CreateScope().
DI in WinForms/WPF: build the host in Sub Main, resolve the main form or window from the container, and pass services via constructors.
30.3 Configuration
Providers: JSON (appsettings.{Environment}.json), environment variables, command-line arguments, User Secrets (development), Azure Key Vault, INI, XML.
The options pattern: IOptions(Of T), IOptionsSnapshot(Of T), IOptionsMonitor(Of T) (reload on change). Validation: .ValidateDataAnnotations().ValidateOnStart()..NET Framework: App.config + ConfigurationManager, plus My.Settings for user settings.
30.4 Logging
ILogger(Of T) with structured logging (message templates {OrderId}), log levels (Trace → Critical), scopes (logger.BeginScope), providers (Console, Debug, EventLog, EventSource).
Third-party: Serilog (sinks: file, Seq, Elasticsearch), NLog. Use LoggerMessage.Define for high-performance logging.