Test dans un environnement réel
Test en production sans filigrane.
Fonctionne partout où vous en avez besoin.
CQRS est l'abréviation de Command Query Responsibility Segregation (séparation des responsabilités en matière d'interrogation des commandes). Il s'agit d'un modèle qui vise à séparer la lecture des données de leur écriture. Cette distinction est cruciale pour plusieurs raisons. Premièrement, il permet une optimisation plus souple de chaque opération, améliorant ainsi les performances et l'évolutivité de l'application. Lorsque vous séparez les commandes(écrit) et les demandes de renseignements(lit)vous pouvez les optimiser indépendamment les uns des autres.
Par exemple, une application complexe peut nécessiter des opérations de lecture rapides mais peut tolérer des opérations d'écriture plus lentes. En appliquant le CQRS, les développeurs peuvent utiliser des modèles de données différents pour les lectures et les écritures, en séparant la couche d'accès aux données pour l'adapter aux besoins spécifiques de chaque opération. Dans cet article, nous allons explorer les concepts du modèle CQRS et du modèleBibliothèque IronPDF pour les développeurs .NET.
Le cœur du CQRS réside dans la séparation des opérations de commande et d'interrogation, chacune traitant des aspects différents de l'interaction avec les données. Il est essentiel de comprendre ces éléments pour mettre en œuvre le modèle de manière efficace.
Requêtes : Les requêtes, gérées par un gestionnaire de requêtes, permettent de récupérer des données ou des objets de transfert de données sans modifier l'état du système. Ce sont les questions que vous posez sur vos données. Par exemple, la recherche du profil d'un utilisateur ou la liste de tous les produits disponibles dans un inventaire sont des requêtes. Les requêtes renvoient des données mais garantissent qu'elles ne modifient pas les données ou leur état.
L'un des outils les plus populaires pour mettre en œuvre le CQRS dans les applications .NET est MediatR, une bibliothèque de modèles de médiateurs. Il permet de réduire le couplage entre les composants d'une application, en les faisant communiquer indirectement. MediatR facilite le traitement des commandes et des requêtes en jouant le rôle de médiateur entre la commande/requête et son gestionnaire.
La mise en œuvre du modèle CQRS dans ASP.NET Core implique de configurer votre projet de manière à séparer les commandes et les requêtes, en utilisant une bibliothèque comme MediatR pour assurer la médiation entre les deux. Voici un aperçu simplifié de la manière dont vous pouvez configurer le CQRS dans votre application ASP.NET Core.
Démarrez Visual Studio et choisissez de créer un nouveau projet.
Recherchez et sélectionnez un type de projet "Application Web ASP.NET Core". Cliquez sur Suivant.
Donnez un nom à votre projet et définissez son emplacement. Cliquez sur Créer.
Ensuite, vous devez organiser votre projet pour le CQRS. Vous pouvez le faire en ajoutant des dossiers pour séparer les commandes, les requêtes et les interfaces communes qu'ils utiliseront. Dans l'explorateur de solutions, faites un clic droit sur votre projet, cliquez sur "Ajouter", puis sur "Nouveau dossier". Créez trois dossiers : "Commandes", "Requêtes" et "Interfaces".
Dans le dossier "Interfaces", ajoutez des interfaces pour vos commandes et vos requêtes. Pour une commande, vous pouvez avoir une interface ICommandHandler avec une méthode Handle qui prend une commande et exécute l'action. Pour une requête, vous pourriez avoir une interface IQueryHandler avec une méthode Handle qui prend une requête et renvoie des données.
Ajoutons maintenant une commande et une requête pour faire une démonstration. Supposons que votre application gère des tâches et que vous souhaitiez ajouter une tâche(commande) et récupérer les tâches(interrogation).
Dans le dossier "Interfaces", ajoutez deux 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
Dans le dossier "Commands", ajoutez une classe AddItemCommand avec des propriétés pour les détails de la tâche. Ajoutez également une classe AddItemCommandHandler qui implémente ICommandHandler et contient la logique permettant d'ajouter une tâche à la base de données.
Dans le dossier "Queries", ajoutez une classe GetTasksQuery qui représente une demande de tâches. Ajoutez une autre classe GetTasksQueryHandler qui implémente IQueryHandler et contient la logique pour récupérer les tâches de la base de données.
Pour un exemple simple, votre AddItemCommand pourrait ressembler à ceci :
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
Et le AddItemCommandHandler :
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
Votre GetItemsQuery peut être vide s'il n'a pas besoin de paramètres pour récupérer des tâches, et GetItemsQueryHandler peut ressembler à ce qui suit :
public class GetItemsQuery
{
// This class might not need any properties, depending on your query
}
using CQRS_testing.Interfaces;
namespace CQRS_testing.Queries
{
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
}
using CQRS_testing.Interfaces;
namespace CQRS_testing.Queries
{
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
Dans vos contrôleurs ASP.NET, vous utiliserez ces gestionnaires pour traiter les commandes et les requêtes. Pour ajouter une tâche, l'action du contrôleur crée une AddTaskCommand, définit ses propriétés à partir des données du formulaire, puis la transmet à une instance AddTaskCommandHandler pour qu'elle la traite. Pour récupérer les tâches, il appelle un GetTasksQueryHandler pour obtenir les données et les transmettre à la vue.
Une fois vos commandes et vos requêtes configurées, vous pouvez maintenant les utiliser dans vos contrôleurs. Voici comment vous pourriez le faire dans une 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
Pour tout relier, en particulier si vous utilisez l'injection de dépendances(DI) dans ASP.NET Core, vous devrez enregistrer vos gestionnaires de commandes et de requêtes avec le conteneur DI dans le fichier Startup.cs. De cette façon, ASP.NET peut fournir des instances de vos gestionnaires lorsqu'elles sont nécessaires.
Voici un exemple très simple d'enregistrement d'un gestionnaire :
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)()
Dans l'application pratique du CQRS, la distinction entre le modèle de données pour les opérations d'écriture et celui pour les opérations de lecture est fondamentale, car elle garantit que l'architecture prend en charge des approches variées et optimisées pour le traitement des données.
Explore IronPDF pour la gestion des PDF est un outil destiné aux développeurs travaillant avec le langage de programmation C#, leur permettant de créer, lire et modifier des documents PDF directement dans leurs applications. Cette bibliothèque est conviviale et facilite l'intégration de fonctionnalités PDF telles que la génération de rapports PDF, de factures ou d'autres documentscréer des PDF à partir de HTML code. IronPDF prend en charge diverses fonctionnalités, notamment l'édition de texte et d'images dans les PDF, la mise en place d'une sécurité des documents et la conversion de pages web au format PDF. Sa polyvalence et sa facilité d'utilisation en font une ressource précieuse pour les développeurs qui cherchent à mettre en œuvre des opérations PDF dans leurs projets.
IronPDF excelle par sonCapacité de conversion de HTML en PDFla traduction doit être réalisée dans le respect des règles de l'art, en gardant intactes toutes les mises en page et tous les styles. Il crée des PDF à partir de contenus web, adaptés aux rapports, aux factures et à la documentation. Les fichiers HTML, les URL et les chaînes HTML peuvent être convertis en PDF de manière transparente.
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
Voyons maintenant comment IronPDF peut être utilisé dans une application C# en suivant la séparation des responsabilités de la requête de commande(CQRS) modèle. Vous trouverez ci-dessous un exemple simplifié de l'utilisation d'IronPDF dans le cadre d'une configuration CQRS pour générer un rapport PDF. Cet exemple est conceptuel et se concentre sur la génération d'un document PDF en tant que commande.
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
Dans cet exemple, GeneratePdfReportCommand représente une commande dans le modèle CQRS. Il comprend une méthode GenerateReportAsync qui prend reportContent comme une chaîne HTML et un outputPath où le rapport PDF sera sauvegardé. La classe HtmlToPdf d'IronPDF est utilisée pour convertir le contenu HTML au format PDF, qui est ensuite enregistré dans le chemin spécifié. Cette configuration illustre la manière dont vous pouvez intégrer la fonctionnalité de génération de PDF dans l'architecture de votre application, en particulier dans les scénarios nécessitant une séparation claire des préoccupations, comme le préconise le CQRS.
En résumé, la requête de commandement Séparation des responsabilités(CQRS) offre une approche structurée pour séparer les responsabilités de lecture et d'écriture des données dans vos applications. Cette séparation permet non seulement de clarifier l'architecture, mais aussi d'améliorer la flexibilité, l'évolutivité et les performances de vos systèmes. En suivant les étapes décrites ci-dessus, vous pouvez mettre en œuvre le CQRS dans vos applications ASP.NET Core, en utilisant des outils comme MediatR pour rationaliser la communication entre les commandes, les requêtes et leurs gestionnaires.
L'intégration d'IronPDF à votre application basée sur le CQRS élargit encore ses capacités, vous permettant de créer, manipuler et stocker des documents PDF sans effort. Que vous produisiez des rapports, des factures ou toute autre forme de document, les fonctionnalités complètes et la syntaxe simple d'IronPDF en font un outil puissant dans votre boîte à outils de développement. Essayer IronPDF gratuitementvous permettant d'explorer ses capacités avant de vous engager. Pour une utilisation continue, les licences commencent à partir de 399 $, avec différentes options pour répondre aux besoins de votre projet.
9 produits de l'API .NET pour vos documents de bureau