Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O Host Genérico do .NET fornece uma maneira padronizada de configurar e executar aplicativos com suporte interno para DI (injeção de dependência), configuração e registro em log. Os aplicativos do Windows Forms não incluem a integração de Host Genérico por padrão, mas você pode adicioná-la. Este artigo mostra como configurar o Host Genérico em um aplicativo do Windows Forms para injetar serviços em seus formulários.
Pré-requisitos
- O
Microsoft.Extensions.Hostingpacote NuGet.
Configurar o host genérico
A configuração difere ligeiramente entre C# e Visual Basic. Em C#, configure o host diretamente em Program.cs. No Visual Basic, use os eventos de inicialização e desligamento do Application Framework em ApplicationEvents.vb.
Configure o host Program.cs ao lado de ApplicationConfiguration.Initialize():
- Chame
ApplicationConfiguration.Initialize()para configurar os padrões do WinForms, incluindo estilos visuais, modo DPI alto e fontes padrão. - Crie o host com CreateApplicationBuilder e registre serviços.
- Inicie o host e resolva o formulário principal do DI.
- Passe o formulário para Run.
- Pare e descarte o host após o fechamento do formulário.
O código a seguir mostra o completo Program.cs:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace HostBuilderApp;
static class Program
{
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
var builder = Host.CreateApplicationBuilder();
builder.Services.AddHostedService<SampleLifecycleService>();
builder.Services.AddTransient<Form1>();
builder.Services.AddSingleton<IGreetingService, GreetingService>();
IHost host = builder.Build();
host.Start();
Form1 mainForm = host.Services.GetRequiredService<Form1>();
Application.Run(mainForm);
host.StopAsync().GetAwaiter().GetResult();
host.Dispose();
}
}
Registrar e consumir serviços
Com o host configurado, registre serviços personalizados e insira-os em seus formulários. Para criar e registrar um serviço:
Definir uma interface de serviço:
public interface IGreetingService { string GetGreeting(); }Public Interface IGreetingService Function GetGreeting() As String End InterfaceCrie uma classe que implemente a interface. A
GreetingServiceclasse injeta IConfiguration para ler a mensagem de saudação deappsettings.json:public class GreetingService : IGreetingService { private readonly IConfiguration _configuration; public GreetingService(IConfiguration configuration) { _configuration = configuration; } public string GetGreeting() { return _configuration.GetValue<string>("GreetingMessage") ?? "Hello, World!"; } }Public Class GreetingService Implements IGreetingService Private ReadOnly _configuration As IConfiguration Public Sub New(configuration As IConfiguration) _configuration = configuration End Sub Public Function GetGreeting() As String Implements IGreetingService.GetGreeting Dim message As String = _configuration.GetValue(Of String)("GreetingMessage") If message Is Nothing Then Return "Hello, World!" End If Return message End Function End ClassRegistre a interface e a implementação na propriedade do
Servicesbuilder, conforme mostrado na seção Configurar o Host Genérico.
Executar um serviço hospedado
O Host Genérico também pode executar serviços em segundo plano que participam do ciclo de vida do aplicativo. Implemente IHostedService para receber retornos de chamada quando o host for iniciado e parado. Para adicionar um serviço hospedado:
Crie uma classe que implementa IHostedService. A classe a seguir grava na saída de depuração quando o host é iniciado e parado.
public class SampleLifecycleService : IHostedService { public Task StartAsync(CancellationToken cancellationToken) { System.Diagnostics.Debug.WriteLine("SampleLifecycleService: Started."); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { System.Diagnostics.Debug.WriteLine("SampleLifecycleService: Stopped."); return Task.CompletedTask; } }Public Class SampleLifecycleService Implements IHostedService Public Function StartAsync(cancellationToken As CancellationToken) As Task Implements IHostedService.StartAsync System.Diagnostics.Debug.WriteLine("SampleLifecycleService: Started.") Return Task.CompletedTask End Function Public Function StopAsync(cancellationToken As CancellationToken) As Task Implements IHostedService.StopAsync System.Diagnostics.Debug.WriteLine("SampleLifecycleService: Stopped.") Return Task.CompletedTask End Function End ClassRegistre o serviço na propriedade
AddHostedServicedoServicesbuilder, conforme mostrado na seção Configurar o Host Genérico.
O host chama StartAsync na inicialização e StopAsync no desligamento, portanto, a saída de depuração aparece na janela Saída no Visual Studio.
Consumir serviços através de uma interface de formulário
Como Form1 é resolvido do contêiner de DI, a injeção de construtor funciona diretamente:
- Adicione parâmetros de construtor para cada serviço de que o formulário precisa.
- Armazene os serviços injetados em campos privados.
- Utilize os serviços em manipuladores de eventos ou outros métodos.
public partial class Form1 : Form
{
private readonly ILogger<Form1> _logger;
private readonly IGreetingService _greetingService;
public Form1(ILogger<Form1> logger, IGreetingService greetingService)
{
InitializeComponent();
_logger = logger;
_greetingService = greetingService;
}
private void ButtonGreet_Click(object sender, EventArgs e)
{
string greeting = _greetingService.GetGreeting();
lblGreeting.Text = greeting;
_logger.LogInformation("Greeting displayed: {Greeting}", greeting);
}
}
Public Class Form1
Private _logger As ILogger(Of Form1)
Private _greetingService As IGreetingService
Sub New(ILogger As ILogger(Of Form1), greetingService As IGreetingService)
InitializeComponent()
_logger = ILogger
_greetingService = greetingService
End Sub
Private Sub ButtonGreet_Click(sender As Object, e As EventArgs) Handles btnGreet.Click
Dim greeting As String = _greetingService.GetGreeting()
lblGreeting.Text = greeting
_logger.LogInformation("Greeting displayed: {Greeting}", greeting)
End Sub
End Class
Adicionar configuração
CreateApplicationBuilder carrega appsettings.json automaticamente do diretório de saída. Para adicionar um arquivo de configuração:
Crie um
appsettings.jsonarquivo na raiz do projeto com seus valores de configuração:{ "GreetingMessage": "Hello from the Generic Host!" }Defina
CopyToOutputDirectorycomoPreserveNewestno arquivo de projeto, portantoappsettings.json, é copiado para o diretório de saída:<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net10.0-windows</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> <UseWindowsForms>true</UseWindowsForms> </PropertyGroup> <ItemGroup> <None Update="appsettings.json"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.*" /> </ItemGroup> </Project>
Conteúdo relacionado
.NET Desktop feedback