Ir para o conteúdo do rodapé
AJUDA DO .NET

Padrão CQRS em C# (Como funciona para desenvolvedores)

Introdução ao CQRS

CQRS significa Segregação de Responsabilidades de Comando e Consulta. É um padrão que se concentra em separar a leitura dos dados da sua escrita. Essa distinção é crucial por diversos motivos. Em primeiro lugar, permite uma otimização mais flexível de cada operação, melhorando o desempenho e a escalabilidade da aplicação. Ao separar comandos (escritas) e consultas (leituras), você pode otimizá-los independentemente.

Por exemplo, uma aplicação complexa pode exigir operações de leitura rápidas, mas tolerar operações de gravação mais lentas. Ao aplicar o CQRS, os desenvolvedores podem usar diferentes modelos de dados para leituras e gravações, segregando a camada de acesso a dados para se adequar às necessidades específicas de cada operação. Neste artigo, exploraremos os conceitos do padrão CQRS e da biblioteca IronPDF para desenvolvedores .NET .

Conceitos e componentes principais

A essência do CQRS reside na separação das operações de comando e consulta, cada uma lidando com diferentes aspectos da interação com os dados. Compreender esses componentes é crucial para implementar o padrão de forma eficaz.

  • Comandos: São responsáveis ​​por atualizar os dados. Os comandos incorporam uma lógica de negócios complexa e podem alterar o estado dos dados no repositório de dados, agindo sem retornar qualquer informação. Os comandos assumem a função exclusiva de lidar com tarefas de gravação de dados, influenciando diretamente o estado do aplicativo sem produzir qualquer saída. Por exemplo, adicionar um novo usuário ou atualizar os detalhes de um produto existente são ações realizadas por meio de comandos.

  • Consultas: As consultas, gerenciadas por um manipulador de consultas, recuperam dados ou transferem objetos de dados sem alterar o estado do sistema. São as perguntas que você faz sobre seus dados. Por exemplo, obter o perfil de um usuário ou listar todos os produtos disponíveis em um estoque são consultas. As consultas retornam dados, mas garantem que não modifiquem os dados ou seu estado.

Uma das ferramentas populares para implementar CQRS em aplicações .NET é o MediatR, uma biblioteca de padrões de mediação. Isso ajuda a reduzir o acoplamento entre os componentes de uma aplicação, fazendo com que eles se comuniquem indiretamente. O MediatR facilita o processamento de comandos e consultas, atuando como intermediário entre o comando/consulta e seu manipulador.

Implementação prática com ASP.NET Core

Implementar o padrão CQRS no ASP.NET Core envolve configurar seu projeto para separar comandos e consultas, usando uma biblioteca como o MediatR para intermediar a comunicação entre eles. Aqui está uma visão geral simplificada de como você pode configurar o CQRS em sua aplicação ASP.NET Core .

Passo 1: Configure sua aplicação ASP.NET

  1. Inicie o Visual Studio e escolha criar um novo projeto.
  2. Procure e selecione um projeto do tipo "Aplicação Web ASP.NET Core ". Clique em Avançar.

    Padrão CQRS em C# (Como funciona para desenvolvedores): Figura 1 - Criando um novo projeto ASP.NET

  3. Dê um nome ao seu projeto e defina sua localização. Clique em Criar.
  4. Escolha o modelo "Aplicação Web (Model-View-Controller)" para ASP.NET Core. Certifique-se de estar utilizando a versão do .NET Core que atenda às suas necessidades. Clique em Criar.

Etapa 2

Em seguida, você precisará organizar seu projeto para CQRS. Você pode fazer isso adicionando pastas para separar comandos, consultas e as interfaces comuns que eles usarão. No Explorador de Soluções, clique com o botão direito do mouse no seu projeto, vá em "Adicionar" e, em seguida, em "Nova Pasta". Crie três pastas: "Comandos", "Consultas" e "Interfaces".

Na pasta "Interfaces", adicione interfaces para seus comandos e consultas. Para um comando, você pode ter uma interface ICommandHandler com um método Handle que recebe um comando e executa a ação. Para uma consulta, você poderia ter uma interface IQueryHandler com um método Handle que recebe uma consulta e retorna dados.

Padrão CQRS em C# (Como funciona para desenvolvedores): Figura 2 - Exemplo de como os arquivos podem ser organizados

Etapa 3

Agora, vamos adicionar um comando e uma consulta para demonstrar. Suponha que seu aplicativo gerencie tarefas e você queira adicionar uma tarefa (comando) e recuperar tarefas (consulta).

Na pasta "Interfaces", adicione duas interfaces:

// Define interfaces for your handlers:
public interface ICommandHandler<TCommand>
{
    void Handle(TCommand command);
}

public interface IQueryHandler<TQuery, TResult>
{
    TResult Handle(TQuery query);
}
// Define interfaces for your handlers:
public interface ICommandHandler<TCommand>
{
    void Handle(TCommand command);
}

public interface IQueryHandler<TQuery, TResult>
{
    TResult Handle(TQuery query);
}
' Define interfaces for your handlers:
Public Interface ICommandHandler(Of TCommand)
	Sub Handle(ByVal command As TCommand)
End Interface

Public Interface IQueryHandler(Of TQuery, TResult)
	Function Handle(ByVal query As TQuery) As TResult
End Interface
$vbLabelText   $csharpLabel

Na pasta "Comandos", adicione uma classe AddItemCommand com propriedades para os detalhes da tarefa. Adicione também uma classe AddItemCommandHandler que implemente a interface ICommandHandler e contenha a lógica para adicionar uma tarefa ao banco de dados.

Na pasta "Consultas", adicione uma classe GetTasksQuery que represente uma solicitação de tarefas. Adicione outra classe, GetTasksQueryHandler, que implemente a interface IQueryHandler e contenha a lógica para recuperar tarefas do banco de dados.

Para dar um exemplo simples, seu comando AddItemCommand poderia ser assim:

public class AddItemCommand
{
    public string Name { get; set; }
    public int Quantity { get; set; }

    // Constructor
    public AddItemCommand(string name, int quantity)
    {
        Name = name;
        Quantity = quantity;
    }
}
public class AddItemCommand
{
    public string Name { get; set; }
    public int Quantity { get; set; }

    // Constructor
    public AddItemCommand(string name, int quantity)
    {
        Name = name;
        Quantity = quantity;
    }
}
Public Class AddItemCommand
	Public Property Name() As String
	Public Property Quantity() As Integer

	' Constructor
	Public Sub New(ByVal name As String, ByVal quantity As Integer)
		Me.Name = name
		Me.Quantity = quantity
	End Sub
End Class
$vbLabelText   $csharpLabel

E o manipulador de comando AddItem:

public class AddItemCommandHandler : ICommandHandler<AddItemCommand>
{
    public void Handle(AddItemCommand command)
    {
        // Here, you'd add the item to your database, for example, to have employee data stored
        Console.WriteLine($"Adding item: {command.Name} with quantity {command.Quantity}");
        // Add database logic here
    }
}
public class AddItemCommandHandler : ICommandHandler<AddItemCommand>
{
    public void Handle(AddItemCommand command)
    {
        // Here, you'd add the item to your database, for example, to have employee data stored
        Console.WriteLine($"Adding item: {command.Name} with quantity {command.Quantity}");
        // Add database logic here
    }
}
Public Class AddItemCommandHandler
	Implements ICommandHandler(Of AddItemCommand)

	Public Sub Handle(ByVal command As AddItemCommand)
		' Here, you'd add the item to your database, for example, to have employee data stored
		Console.WriteLine($"Adding item: {command.Name} with quantity {command.Quantity}")
		' Add database logic here
	End Sub
End Class
$vbLabelText   $csharpLabel

Sua GetItemsQuery pode estar vazia se não precisar de nenhum parâmetro para buscar tarefas, e o GetItemsQueryHandler pode ter a seguinte aparência:

public class GetItemsQuery
{
    // This class might not need any properties, depending on your query
}

namespace CQRS_testing.Queries
{
    using CQRS_testing.Interfaces;

    public class GetItemsQueryHandler : IQueryHandler<GetItemsQuery, IEnumerable<string>>
    {
        public IEnumerable<string> Handle(GetItemsQuery query)
        {
            // Here, you'd fetch items from your database
            return new List<string> { "Item1", "Item2" };
        }
    }
}
public class GetItemsQuery
{
    // This class might not need any properties, depending on your query
}

namespace CQRS_testing.Queries
{
    using CQRS_testing.Interfaces;

    public class GetItemsQueryHandler : IQueryHandler<GetItemsQuery, IEnumerable<string>>
    {
        public IEnumerable<string> Handle(GetItemsQuery query)
        {
            // Here, you'd fetch items from your database
            return new List<string> { "Item1", "Item2" };
        }
    }
}
Imports CQRS_testing.Interfaces

Public Class GetItemsQuery
	' This class might not need any properties, depending on your query
End Class

Namespace CQRS_testing.Queries

	Public Class GetItemsQueryHandler
		Implements IQueryHandler(Of GetItemsQuery, IEnumerable(Of String))

		Public Function Handle(ByVal query As GetItemsQuery) As IEnumerable(Of String)
			' Here, you'd fetch items from your database
			Return New List(Of String) From {"Item1", "Item2"}
		End Function
	End Class
End Namespace
$vbLabelText   $csharpLabel

Em seus controladores ASP.NET , você usará esses manipuladores para processar comandos e consultas. Para adicionar uma tarefa, a ação do controlador criaria um AddTaskCommand , definiria suas propriedades a partir dos dados do formulário e, em seguida, o passaria para uma instância de AddTaskCommandHandler para ser processado. Para recuperar tarefas, seria chamado um GetTasksQueryHandler para obter os dados e passá-los para a visualização.

Conectando-o a um controlador

Com seus comandos e consultas configurados, agora você pode usá-los em seus controladores. Eis como você pode fazer isso em uma classe ItemsController :

public class ItemsController : Controller
{
    private readonly ICommandHandler<AddItemCommand> _addItemHandler;
    private readonly IQueryHandler<GetItemsQuery, IEnumerable<string>> _getItemsHandler;

    // Constructor injection is correctly utilized here
    public ItemsController(ICommandHandler<AddItemCommand> addItemHandler, IQueryHandler<GetItemsQuery, IEnumerable<string>> getItemsHandler)
    {
        _addItemHandler = addItemHandler;
        _getItemsHandler = getItemsHandler;
    }

    public IActionResult Index()
    {
        // Use the injected _getItemsHandler instead of creating a new instance
        var query = new GetItemsQuery();
        var items = _getItemsHandler.Handle(query);
        return View(items);
    }

    [HttpPost]
    public IActionResult Add(string name, int quantity)
    {
        // Use the injected _addItemHandler instead of creating a new instance
        var command = new AddItemCommand(name, quantity);
        _addItemHandler.Handle(command);
        return RedirectToAction("Index");
    }
}
public class ItemsController : Controller
{
    private readonly ICommandHandler<AddItemCommand> _addItemHandler;
    private readonly IQueryHandler<GetItemsQuery, IEnumerable<string>> _getItemsHandler;

    // Constructor injection is correctly utilized here
    public ItemsController(ICommandHandler<AddItemCommand> addItemHandler, IQueryHandler<GetItemsQuery, IEnumerable<string>> getItemsHandler)
    {
        _addItemHandler = addItemHandler;
        _getItemsHandler = getItemsHandler;
    }

    public IActionResult Index()
    {
        // Use the injected _getItemsHandler instead of creating a new instance
        var query = new GetItemsQuery();
        var items = _getItemsHandler.Handle(query);
        return View(items);
    }

    [HttpPost]
    public IActionResult Add(string name, int quantity)
    {
        // Use the injected _addItemHandler instead of creating a new instance
        var command = new AddItemCommand(name, quantity);
        _addItemHandler.Handle(command);
        return RedirectToAction("Index");
    }
}
Public Class ItemsController
	Inherits Controller

	Private ReadOnly _addItemHandler As ICommandHandler(Of AddItemCommand)
	Private ReadOnly _getItemsHandler As IQueryHandler(Of GetItemsQuery, IEnumerable(Of String))

	' Constructor injection is correctly utilized here
	Public Sub New(ByVal addItemHandler As ICommandHandler(Of AddItemCommand), ByVal getItemsHandler As IQueryHandler(Of GetItemsQuery, IEnumerable(Of String)))
		_addItemHandler = addItemHandler
		_getItemsHandler = getItemsHandler
	End Sub

	Public Function Index() As IActionResult
		' Use the injected _getItemsHandler instead of creating a new instance
		Dim query = New GetItemsQuery()
		Dim items = _getItemsHandler.Handle(query)
		Return View(items)
	End Function

	<HttpPost>
	Public Function Add(ByVal name As String, ByVal quantity As Integer) As IActionResult
		' Use the injected _addItemHandler instead of creating a new instance
		Dim command = New AddItemCommand(name, quantity)
		_addItemHandler.Handle(command)
		Return RedirectToAction("Index")
	End Function
End Class
$vbLabelText   $csharpLabel

Para configurar tudo, especialmente se você estiver usando Injeção de Dependência (DI) no ASP.NET Core, será necessário registrar seus manipuladores de comandos e consultas no contêiner de DI no arquivo Startup.cs . Dessa forma, o ASP.NET poderá fornecer instâncias dos seus manipuladores quando necessário.

Aqui está um exemplo muito básico de como registrar um manipulador:

builder.Services.AddTransient<ICommandHandler<AddItemCommand>, AddItemCommandHandler>();
builder.Services.AddTransient<IQueryHandler<GetItemsQuery, IEnumerable<string>>, GetItemsQueryHandler>();
builder.Services.AddTransient<ICommandHandler<AddItemCommand>, AddItemCommandHandler>();
builder.Services.AddTransient<IQueryHandler<GetItemsQuery, IEnumerable<string>>, GetItemsQueryHandler>();
builder.Services.AddTransient(Of ICommandHandler(Of AddItemCommand), AddItemCommandHandler)()
builder.Services.AddTransient(Of IQueryHandler(Of GetItemsQuery, IEnumerable(Of String)), GetItemsQueryHandler)()
$vbLabelText   $csharpLabel

Na aplicação prática do CQRS, a distinção entre o modelo de dados para operações de escrita e o modelo para operações de leitura é fundamental, garantindo que a arquitetura suporte abordagens variadas e otimizadas para o tratamento de dados.

IronPDF: Biblioteca PDF em C

Padrão CQRS em C# (Como funciona para desenvolvedores): Figura 3 - Página web do IronPDF

Explore o IronPDF para gerenciamento de PDFs, uma ferramenta para desenvolvedores que trabalham com a linguagem de programação C#, permitindo criar, ler e editar documentos PDF diretamente em seus aplicativos. Esta biblioteca é fácil de usar, simplificando a integração de funcionalidades de PDF, como a geração de relatórios e faturas em PDF, ou a criação de PDFs a partir de código HTML . O IronPDF oferece suporte a vários recursos, incluindo edição de texto e imagens em PDFs, configuração de segurança de documentos e conversão de páginas da web para o formato PDF. Sua versatilidade e facilidade de uso o tornam um recurso valioso para desenvolvedores que buscam implementar operações com PDFs em seus projetos.

O IronPDF se destaca por sua capacidade de conversão de HTML para PDF , mantendo todos os layouts e estilos intactos. Ele cria PDFs a partir de conteúdo da web, adequados para relatórios, faturas e documentação. Arquivos HTML, URLs e strings HTML podem ser convertidos em PDFs sem problemas.

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()

		' 1. Convert HTML String to PDF
		Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
		Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
		pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")

		' 2. Convert HTML File to PDF
		Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
		Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
		pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")

		' 3. Convert URL to PDF
		Dim url = "http://ironpdf.com" ' Specify the URL
		Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
		pdfFromUrl.SaveAs("URLToPDF.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

Exemplo de código

Agora, vamos explorar como o IronPDF pode ser utilizado em uma aplicação C# seguindo o padrão CQRS (Command Query Responsibility Segregation). A seguir, um exemplo simplificado que demonstra como você pode usar o IronPDF em uma configuração CQRS para gerar um relatório em PDF. Este exemplo é conceitual e foca na geração de um documento PDF como um comando.

using IronPdf;
using System.Threading.Tasks;

namespace PdfGenerationApp.Commands
{
    public class GeneratePdfReportCommand
    {
        // Command handler that generates a PDF report
        public async Task GenerateReportAsync(string reportContent, string outputPath)
        {
            // Initialize the IronPDF HTML to PDF renderer
            var renderer = new ChromePdfRenderer();
            // Use IronPDF to generate a PDF from HTML content
            var pdf = await Task.Run(() => renderer.RenderHtmlAsPdf(reportContent));
            // Save the generated PDF to a specified path
            pdf.SaveAs(outputPath);
        }
    }
}
using IronPdf;
using System.Threading.Tasks;

namespace PdfGenerationApp.Commands
{
    public class GeneratePdfReportCommand
    {
        // Command handler that generates a PDF report
        public async Task GenerateReportAsync(string reportContent, string outputPath)
        {
            // Initialize the IronPDF HTML to PDF renderer
            var renderer = new ChromePdfRenderer();
            // Use IronPDF to generate a PDF from HTML content
            var pdf = await Task.Run(() => renderer.RenderHtmlAsPdf(reportContent));
            // Save the generated PDF to a specified path
            pdf.SaveAs(outputPath);
        }
    }
}
Imports IronPdf
Imports System.Threading.Tasks

Namespace PdfGenerationApp.Commands
	Public Class GeneratePdfReportCommand
		' Command handler that generates a PDF report
		Public Async Function GenerateReportAsync(ByVal reportContent As String, ByVal outputPath As String) As Task
			' Initialize the IronPDF HTML to PDF renderer
			Dim renderer = New ChromePdfRenderer()
			' Use IronPDF to generate a PDF from HTML content
			Dim pdf = Await Task.Run(Function() renderer.RenderHtmlAsPdf(reportContent))
			' Save the generated PDF to a specified path
			pdf.SaveAs(outputPath)
		End Function
	End Class
End Namespace
$vbLabelText   $csharpLabel

Neste exemplo, GeneratePdfReportCommand representa um comando no padrão CQRS. Inclui um método GenerateReportAsync que recebe reportContent como uma string HTML e um outputPath onde o relatório em PDF será salvo. A classe HtmlToPdf do IronPDF é usada para converter o conteúdo HTML para o formato PDF, que é então salvo no caminho especificado. Esta configuração ilustra como você pode integrar a funcionalidade de geração de PDF na arquitetura do seu aplicativo, especialmente em cenários que exigem uma clara separação de responsabilidades, conforme promovido pelo CQRS.

Padrão CQRS em C# (Como funciona para desenvolvedores): Figura 4 - PDF gerado

Conclusão

Padrão CQRS em C# (Como funciona para desenvolvedores): Figura 5 - Informações de licença do IronPDF

Em resumo, o padrão Command Query Responsibility Segregation (CQRS) oferece uma abordagem estruturada para separar as responsabilidades de leitura e gravação de dados em seus aplicativos. Essa separação não apenas esclarece a arquitetura, mas também aumenta a flexibilidade, a escalabilidade e o desempenho de seus sistemas. Seguindo os passos descritos acima, você pode implementar CQRS em suas aplicações ASP.NET Core , utilizando ferramentas como o MediatR para agilizar a comunicação entre comandos, consultas e seus respectivos manipuladores.

A integração do IronPDF em seu aplicativo baseado em CQRS expande ainda mais suas capacidades, permitindo que você crie, manipule e armazene documentos PDF sem esforço. Seja para gerar relatórios, faturas ou qualquer tipo de documento, os recursos abrangentes e a sintaxe simples do IronPDF o tornam uma ferramenta poderosa em seu conjunto de ferramentas de desenvolvimento. O IronPDF oferece um período de teste gratuito , dando-lhe a oportunidade de explorar as suas funcionalidades antes de se comprometer. Para uso contínuo, as licenças começam em $799, oferecendo diversas opções para atender às necessidades do seu projeto.

Perguntas frequentes

O que é o padrão CQRS no desenvolvimento de software?

O padrão CQRS, ou Segregação de Responsabilidades de Comando e Consulta, é uma estratégia de design que separa a leitura da escrita de dados em aplicações. Essa separação permite a otimização independente das operações de comando (escrita) e consulta (leitura), melhorando o desempenho e a escalabilidade.

Como o CQRS pode melhorar o desempenho em aplicações .NET?

O CQRS melhora o desempenho em aplicações .NET ao utilizar modelos de dados distintos para operações de leitura e gravação, permitindo que os desenvolvedores otimizem cada parte independentemente. Isso resulta em maior escalabilidade e eficiência no tratamento de lógicas de negócios complexas.

Quais são as vantagens de usar o MediatR em uma configuração CQRS?

MediatR é uma biblioteca de padrões de mediação que facilita o CQRS reduzindo o acoplamento entre componentes em aplicações .NET. Ela atua como intermediária, gerenciando as interações entre comandos, consultas e seus respectivos manipuladores.

Como o IronPDF complementa o padrão CQRS em aplicações C#?

O IronPDF complementa o padrão CQRS ao fornecer recursos robustos de manipulação de PDFs. Ele permite que os desenvolvedores gerem, leiam e editem documentos PDF dentro de aplicativos, tornando-o ideal para a criação de relatórios em PDF como parte de operações de comando em uma configuração CQRS.

Por que é vantajoso separar comandos e consultas em um projeto ASP.NET Core?

Separar comandos e consultas em um projeto ASP.NET Core aprimora a organização e a clareza. Isso permite que os desenvolvedores gerenciem cada aspecto de forma independente, melhorando a manutenção e alinhando-se aos princípios do padrão CQRS.

Qual o papel da injeção de dependência em uma arquitetura CQRS?

A injeção de dependência é crucial na arquitetura CQRS, pois permite o registro e o provisionamento contínuos de manipuladores de comandos e consultas. Isso garante que os aplicativos ASP.NET Core possam resolver dependências de forma eficiente e gerenciar instâncias de manipuladores conforme necessário.

Como posso converter HTML para PDF em C# usando uma biblioteca?

Você pode usar o método RenderHtmlAsPdf do IronPDF para converter strings HTML em PDFs. Ele também suporta a conversão de arquivos HTML em PDFs usando o RenderHtmlFileAsPdf , o que é útil para gerar relatórios e documentação.

Posso avaliar uma biblioteca PDF em C# antes de comprá-la?

Sim, o IronPDF oferece uma versão de avaliação gratuita, permitindo que os desenvolvedores explorem seus recursos e funcionalidades antes de tomar uma decisão de compra.

Curtis Chau
Redator Técnico

Curtis Chau é bacharel em Ciência da Computação (Universidade Carleton) e se especializa em desenvolvimento front-end, com experiência em Node.js, TypeScript, JavaScript e React. Apaixonado por criar interfaces de usuário intuitivas e esteticamente agradáveis, Curtis gosta de trabalhar com frameworks modernos e criar manuais ...

Leia mais

Equipe de suporte de ferro

Estamos online 24 horas por dia, 5 dias por semana.
Bater papo
E-mail
Liga para mim