Migrer d'Infragistics Barcode à IronBarcode
La plupart des migrations de codes-barres Infragisticsont lieu parce que l'équipe avait besoin de la lecture de codes-barres dans un projet où seule la génération était disponible (WinForms, ASP.NET Coreou tout projet en dehors de WPF), ou parce que l'API de lecture WPF événementielle s'est avérée trop fragile pour une utilisation en production. Le motif de pont TaskCompletionSource, le champ partagé _result qui rend les appels concurrents non sûrs, et les échecs silencieux dus à l'absence de drapeaux SymbologyType manquants sont toutes des raisons courantes pour lesquelles les équipes recherchent une alternative.
Ce guide décrit l'intégralité de la migration : suppression des packages de codes-barres Infragistics, remplacement du code de génération et de lecture dans les contextes WinForms et WPF, et ajout de la fonctionnalité de code-barres aux types de projets pour lesquels Infragisticsn'était absolument pas pris en charge.
Démarrage rapide
Étape 1 : Retirer les emballages à code-barres Infragistics
Supprimez les packages NuGet de codes-barres Infragisticsde votre projet. Selon les cibles que vous utilisiez :
# WinForms generation package
dotnet remove package Infragistics.WinForms.Barcode
# WPF reading package
dotnet remove package Infragistics.WPF.BarcodeReader
Si votre fichier de projet fait référence aux deux, supprimez-les tous les deux. La licence InfragisticsUltimate n'est pas affectée par la suppression des packages spécifiques aux codes-barres si vous utilisez d'autres composants Infragistics.
Étape 2 : Installer IronBarcode
dotnet add package IronBarcode
IronBarcode est un package unique qui fonctionne sur WinForms, WPF, ASP.NET Core, console, Blazor Server, Docker, Azure Functionset AWS Lambda. Vous n'avez pas besoin de packages séparés par framework.
Étape 3 : Mise à jour des espaces de noms
Remplacez les espaces de noms de code-barres Infragisticspar IronBarCode (B majuscule, C majuscule) :
// Remove these:
// using Infragistics.Win.UltraWinBarcode;
// using Infragistics.Controls.Barcodes;
// using System.Windows.Media.Imaging; // if only used for barcode BitmapImage loading
// Add this:
using IronBarCode;Imports IronBarCodeÉtape 4 : Initialiser la licence
Ajoutez l'initialisation de licence une fois au démarrage de l'application — Program.cs, App.xaml.cs, ou votre racine de composition DI :
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"Exemples de migration de code
Génération WinForms : UltraWinBarcode vers BarcodeWriter
Le schéma de génération WinForms s'adapte parfaitement à BarcodeWriter de Code-barres IronBarcode :
Avant (Infragistics WinForms) :
using Infragistics.Win.UltraWinBarcode;
var barcode = new UltraWinBarcode();
barcode.Symbology = Symbology.Code128;
barcode.Data = "ITEM-12345";
barcode.SaveTo(outputPath);Imports Infragistics.Win.UltraWinBarcode
Dim barcode As New UltraWinBarcode()
barcode.Symbology = Symbology.Code128
barcode.Data = "ITEM-12345"
barcode.SaveTo(outputPath)Après (IronBarcode) :
// NuGet: dotnet add package IronBarcode
using IronBarCode;
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128)
.SaveAsPng(outputPath);Imports IronBarCode
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128) _
.SaveAsPng(outputPath)La valeur d'énumération Symbology d'Infragistics est transférée à l'énumération BarcodeEncoding, qui est un paramètre de CreateBarcode() plutôt qu'une affectation de propriété. Les données deviennent le premier argument. SaveTo() devient .SaveAsPng(), .SaveAsJpeg(), .SaveAsSvg(), ou .SaveAsPdf() selon votre format de sortie.
Si vous devez redimensionner le code-barres avant de l'enregistrer :
using IronBarCode;
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128)
.ResizeTo(400, 100)
.SaveAsPng(outputPath);Imports IronBarCode
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128) _
.ResizeTo(400, 100) _
.SaveAsPng(outputPath)Lecture événementielle WPF : une classe de service sur deux lignes
Il s'agit de la réduction la plus significative de la migration. Le modèle de lecture InfragisticsWPF nécessite une classe de service complète :
Avant (Infragistics WPF — ~35 lignes) :
using Infragistics.Controls.Barcodes;
using System.Windows.Media.Imaging;
private BarcodeReader _reader;
private TaskCompletionSource<string> _result;
public InfragisticsBarcodeService()
{
_reader = new BarcodeReader();
_reader.DecodeComplete += OnDecodeComplete;
}
public async Task<string> ReadBarcodeAsync(string imagePath)
{
_result = new TaskCompletionSource<string>();
var bitmap = new BitmapImage(new Uri(imagePath, UriKind.Absolute));
_reader.SymbologyTypes = Symbology.Code128 |
Symbology.Code39 |
Symbology.QRCode |
Symbology.EAN8 |
Symbology.EAN13 |
Symbology.UpcA |
Symbology.Interleaved2Of5;
_reader.Decode(bitmap);
return await _result.Task;
}
private void OnDecodeComplete(object sender, ReaderDecodeArgs e)
{
_result?.TrySetResult(e.Value ?? "No barcode found");
}
public void Dispose()
{
if (_reader != null)
{
_reader.DecodeComplete -= OnDecodeComplete;
_reader = null;
}
}Imports Infragistics.Controls.Barcodes
Imports System.Windows.Media.Imaging
Imports System.Threading.Tasks
Private _reader As BarcodeReader
Private _result As TaskCompletionSource(Of String)
Public Sub New()
_reader = New BarcodeReader()
AddHandler _reader.DecodeComplete, AddressOf OnDecodeComplete
End Sub
Public Async Function ReadBarcodeAsync(imagePath As String) As Task(Of String)
_result = New TaskCompletionSource(Of String)()
Dim bitmap As New BitmapImage(New Uri(imagePath, UriKind.Absolute))
_reader.SymbologyTypes = Symbology.Code128 Or
Symbology.Code39 Or
Symbology.QRCode Or
Symbology.EAN8 Or
Symbology.EAN13 Or
Symbology.UpcA Or
Symbology.Interleaved2Of5
_reader.Decode(bitmap)
Return Await _result.Task
End Function
Private Sub OnDecodeComplete(sender As Object, e As ReaderDecodeArgs)
_result?.TrySetResult(If(e.Value, "No barcode found"))
End Sub
Public Sub Dispose()
If _reader IsNot Nothing Then
RemoveHandler _reader.DecodeComplete, AddressOf OnDecodeComplete
_reader = Nothing
End If
End SubAprès (IronBarcode — 2 lignes) :
using IronBarCode;
var results = BarcodeReader.Read(imagePath);
return results.FirstOrDefault()?.Value ?? "No barcode found";Imports IronBarCode
Dim results = BarcodeReader.Read(imagePath)
Return If(results.FirstOrDefault()?.Value, "No barcode found")Toute la classe de service — gestion des instances, gestion des événements, TaskCompletionSource, chargement de BitmapImage, Dispose() — a disparu. BarcodeReader.Read() est synchrone, statique et accepte directement une chaîne de chemin de fichier.
Si vous renvoyiez également le type de symbologie :
using IronBarCode;
var results = BarcodeReader.Read(imagePath);
var first = results.FirstOrDefault();
if (first != null)
{
Console.WriteLine($"Value: {first.Value}, Format: {first.Format}");
}Imports IronBarCode
Dim results = BarcodeReader.Read(imagePath)
Dim first = results.FirstOrDefault()
If first IsNot Nothing Then
Console.WriteLine($"Value: {first.Value}, Format: {first.Format}")
End Ifresult.Value remplace e.Value. result.Format remplace e.Symbology.
Ajout de la lecture WinForms (auparavant impossible)
Si vous travailliez sur un projet WinForms ne comportant que la génération, la lecture est désormais disponible avec le même package :
using IronBarCode;
// In a WinForms button handler or service method — same API as WPF or ASP.NET Core
var results = BarcodeReader.Read(imagePath);
foreach (var result in results)
{
MessageBox.Show($"Found: {result.Value} ({result.Format})");
}Imports IronBarCode
' In a WinForms button handler or service method — same API as WPF or ASP.NET Core
Dim results = BarcodeReader.Read(imagePath)
For Each result In results
MessageBox.Show($"Found: {result.Value} ({result.Format})")
NextAucun paquet supplémentaire, aucune configuration spécifique au framework. Le même appel BarcodeReader.Read() fonctionne dans WinForms comme dans WPF.
Point de terminaison ASP.NET Core(Auparavant impossible)
La génération et la lecture de codes-barres dans un contrôleur ASP.NET Coren'étaient pas possibles avec les packages Infragistics. Avec IronBarcode:
using IronBarCode;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/barcode")]
public class BarcodeController : ControllerBase
{
[HttpPost("read")]
public IActionResult ReadBarcode(IFormFile imageFile)
{
using var stream = imageFile.OpenReadStream();
var results = BarcodeReader.Read(stream);
var values = results.Select(r => new { r.Value, Format = r.Format.ToString() });
return Ok(values);
}
[HttpGet("generate")]
public IActionResult GenerateBarcode([FromQuery] string data)
{
var bytes = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ResizeTo(400, 100)
.ToPngBinaryData();
return File(bytes, "image/png");
}
}Imports IronBarCode
Imports Microsoft.AspNetCore.Mvc
<ApiController>
<Route("api/barcode")>
Public Class BarcodeController
Inherits ControllerBase
<HttpPost("read")>
Public Function ReadBarcode(imageFile As IFormFile) As IActionResult
Using stream = imageFile.OpenReadStream()
Dim results = BarcodeReader.Read(stream)
Dim values = results.Select(Function(r) New With {Key .Value = r.Value, Key .Format = r.Format.ToString()})
Return Ok(values)
End Using
End Function
<HttpGet("generate")>
Public Function GenerateBarcode(<FromQuery> data As String) As IActionResult
Dim bytes = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128) _
.ResizeTo(400, 100) _
.ToPngBinaryData()
Return File(bytes, "image/png")
End Function
End ClassBarcodeReader.Read() accepte un Stream directement — pas besoin d'enregistrer le téléchargement sur le disque au préalable.
Lecture de codes-barres PDF
IronBarcode lit nativement les codes-barres des documents PDF — aucun package supplémentaire n'est requis :
using IronBarCode;
// Read all barcodes from every page of a PDF
var results = BarcodeReader.Read("document.pdf");
foreach (var result in results)
{
Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.Format})");
}Imports IronBarCode
' Read all barcodes from every page of a PDF
Dim results = BarcodeReader.Read("document.pdf")
For Each result In results
Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.Format})")
NextInfragistics n'avait pas d'équivalent : la lecture des codes-barres PDF nécessitait la conversion externe des pages PDF en images avant la numérisation.
Traitement par lots : du séquentiel au parallèle
Avant (Infragistics — séquentiel, non compatible avec la parallélisation en cas de concurrence) :
// Must process one at a time — shared _result field is not thread-safe
var service = new InfragisticsBarcodeService();
var results = new List<string>();
foreach (var file in imageFiles)
{
var value = await service.ReadBarcodeAsync(file);
results.Add(value);
}
service.Dispose();Imports System.Collections.Generic
' Must process one at a time — shared _result field is not thread-safe
Dim service As New InfragisticsBarcodeService()
Dim results As New List(Of String)()
For Each file In imageFiles
Dim value As String = Await service.ReadBarcodeAsync(file)
results.Add(value)
Next
service.Dispose()Après (IronBarcode — parallèle, thread-safe) :
using IronBarCode;
// Option 1: pass an array directly — Code-barres IronBarcode handles parallelization internally
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
var results = BarcodeReader.Read(imageFiles.ToArray(), options);
foreach (var result in results)
{
Console.WriteLine($"{result.Value} ({result.Format})");
}
using IronBarCode;
using System.Collections.Concurrent;
// Option 2: Parallel.ForEach — static BarcodeReader.Read is thread-safe
var allValues = new ConcurrentBag<string>();
Parallel.ForEach(imageFiles, file =>
{
var results = BarcodeReader.Read(file);
foreach (var r in results)
allValues.Add(r.Value);
});Imports IronBarCode
Imports System.Collections.Concurrent
' Option 2: Parallel.ForEach — static BarcodeReader.Read is thread-safe
Dim allValues As New ConcurrentBag(Of String)()
Parallel.ForEach(imageFiles, Sub(file)
Dim results = BarcodeReader.Read(file)
For Each r In results
allValues.Add(r.Value)
Next
End Sub)Suppression du modèle Dispose
Si votre code comportait des implémentations IDisposable autour de BarcodeReader d'Infragistics, celles-ci peuvent être supprimées entièrement. BarcodeReader de Code-barres IronBarcode est une classe statique. Il n'y a aucune instance à créer, aucun gestionnaire d'événements à détacher, et aucun Dispose() à appeler.
// Before: service registered as IDisposable in DI container
services.AddScoped<InfragisticsBarcodeService>(); // implements IDisposable
// After: no registration needed — use static method directly, or wrap in thin service if preferred
// services.AddScoped<IBarcodeService, IronBarcodeService>();' Before: service registered as IDisposable in DI container
services.AddScoped(Of InfragisticsBarcodeService)() ' implements IDisposable
' After: no registration needed — use static method directly, or wrap in thin service if preferred
' services.AddScoped(Of IBarcodeService, IronBarcodeService)()Un service d'encapsulation léger pour les besoins de l'injection de dépendances est simple :
using IronBarCode;
public class BarcodeService
{
public IEnumerable<string> Read(string path)
=> BarcodeReader.Read(path).Select(r => r.Value);
public byte[] Generate(string data, BarcodeEncoding encoding)
=> BarcodeWriter.CreateBarcode(data, encoding).ToPngBinaryData();
}Imports IronBarCode
Public Class BarcodeService
Public Function Read(path As String) As IEnumerable(Of String)
Return BarcodeReader.Read(path).Select(Function(r) r.Value)
End Function
Public Function Generate(data As String, encoding As BarcodeEncoding) As Byte()
Return BarcodeWriter.CreateBarcode(data, encoding).ToPngBinaryData()
End Function
End ClassPas d'injection de constructeur, pas de Dispose(), pas de gestion des événements.
Problèmes de migration courants
Indicateurs de type de symbologie supprimés
La propriété SymbologyTypes du lecteur WPF Infragisticsvous obligeait à énumérer chaque format de code-barres que vous souhaitiez prendre en charge. Code-barres IronBarcode est sans équivalent : il détecte automatiquement plus de 50 formats pris en charge à chaque lecture.
Cela a un effet secondaire important : si un format particulier de code-barres échouait silencieusement auparavant parce que son drapeau SymbologyType manquait dans la liste, Code-barres IronBarcode le détectera désormais. Vous pourriez voir apparaître en production des valeurs de code-barres qui étaient auparavant ignorées sans que vous les ayez prises en compte. C'est le comportement normal — ces codes-barres ont toujours été présents.
Si vous avez besoin de limiter les formats retournés (pour des raisons de performance ou d'ambiguïté), BarcodeReaderOptions le permet :
using IronBarCode;
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = false
};
var results = BarcodeReader.Read(imagePath, options);Imports IronBarCode
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = False
}
Dim results = BarcodeReader.Read(imagePath, options)Chargement de l'image bitmap non nécessaire
Le lecteur WPF Infragisticsnécessitait le chargement des images sous forme d'objets BitmapSource via new BitmapImage(new Uri(path, UriKind.Absolute)). Code-barres IronBarcode accepte directement les chaînes de chemin de fichier, les tableaux d'octets et les flux :
// All of these work — no BitmapImage conversion needed
BarcodeReader.Read("path/to/image.png");
BarcodeReader.Read(File.ReadAllBytes("path/to/image.png"));
BarcodeReader.Read(File.OpenRead("path/to/image.png"));' All of these work — no BitmapImage conversion needed
BarcodeReader.Read("path/to/image.png")
BarcodeReader.Read(File.ReadAllBytes("path/to/image.png"))
BarcodeReader.Read(File.OpenRead("path/to/image.png"))Vous pouvez supprimer toutes les importations using System.Windows.Media.Imaging; qui n'étaient présentes que pour le chargement d'images liées aux codes-barres.
Modèle TaskCompletionSource supprimé
Le champ TaskCompletionSource<string> qui faisait le pont avec la fonction de rappel DecodeComplete événementielle en code asynchrone a entièrement disparu. BarcodeReader.Read() est synchrone et renvoie ses résultats directement.
Si votre code appelant était await service.ReadBarcodeAsync(path), vous pouvez simplifier à :
// Before
var value = await service.ReadBarcodeAsync(imagePath);
// After
var value = BarcodeReader.Read(imagePath).FirstOrDefault()?.Value ?? "No barcode found";netSi vous souhaitez préserver une interface asynchrone pour les appelants en aval sans bloquer un thread :
public Task<string> ReadBarcodeAsync(string imagePath)
{
return Task.Run(() =>
{
var results = BarcodeReader.Read(imagePath);
return results.FirstOrDefault()?.Value ?? "No barcode found";
});
}Option Strict On
Option Infer On
Public Function ReadBarcodeAsync(imagePath As String) As Task(Of String)
Return Task.Run(Function()
Dim results = BarcodeReader.Read(imagePath)
Return If(results.FirstOrDefault()?.Value, "No barcode found")
End Function)
End FunctionChangements de nom de propriété
| Infragistics | Code-barres IronBarcode |
|---|---|
e.Value (dans ReaderDecodeArgs) | result.Value |
e.Symbology (dans ReaderDecodeArgs) | result.Format |
barcode.Data | Premier argument de BarcodeWriter.CreateBarcode() |
barcode.Symbology = Symbology.Code128 | BarcodeEncoding.Code128 (paramètre) |
barcode.SaveTo(path) | .SaveAsPng(path) / .SaveAsJpeg(path) / .SaveAsSvg(path) |
Liste de contrôle de la migration
Utilisez ces modèles grep pour trouver toutes les utilisations des codes-barres Infragisticsdans votre code source :
# Namespace references
grep -r "Infragistics.WinForms.Barcode\|Infragistics.Win.UltraWinBarcode" --include="*.cs" .
grep -r "Infragistics.Controls.Barcodes" --include="*.cs" .
grep -r "Infragistics.WPF.BarcodeReader" --include="*.csproj" .
# WinForms generation types
grep -r "UltraWinBarcode" --include="*.cs" .
grep -r "Symbology\.Code" --include="*.cs" .
grep -r "barcode\.SaveTo(" --include="*.cs" .
# WPF reading types and patterns
grep -r "new BarcodeReader()" --include="*.cs" .
grep -r "DecodeComplete" --include="*.cs" .
grep -r "ReaderDecodeArgs" --include="*.cs" .
grep -r "SymbologyType\." --include="*.cs" .
grep -r "e\.Value\|ReaderDecodeArgs" --include="*.cs" .
grep -r "BitmapImage" --include="*.cs" .
# TaskCompletionSource usage (likely barcode-related if near above patterns)
grep -r "TaskCompletionSource" --include="*.cs" .
Analysez chaque match :
- Utilisations de
UltraWinBarcode: remplacer parBarcodeWriter.CreateBarcode() - Blocs
new BarcodeReader()+DecodeComplete: remplacer parBarcodeReader.Read() - Listes de drapeaux
SymbologyType: supprimer complètement - Chargements
BitmapImageutilisés pour l'entrée de code-barres : remplacer par chemin/direct/flux/octets - Corps de rappel
ReaderDecodeArgs e: extrairee.Value→result.Value,e.Symbology→result.Format IDisposablesur les classes de service de code-barres : supprimer si la seule ressource éliminable était_reader
Comparaison des fonctionnalités
| Fonction | Code-barres Infragistics | Code-barres IronBarcode |
|---|---|---|
| génération de codes-barres WinForms | Oui (UltraWinBarcode) | Oui |
| Lecture de codes-barres WinForms | Non disponible | Oui |
| génération de codes-barres WPF | Oui (XamBarcode) | Oui |
| Lecture de codes-barres WPF | Oui (piloté par les événements) | Oui (synchrone) |
| ASP.NET Core | Non disponible | Oui |
| Service Console / Worker | Non disponible | Oui |
| Docker / Linux | Non disponible | Oui |
| Azure Functions | Non disponible | Oui |
| Serveur Blazor | Non disponible | Oui |
| Détection automatique du format | Non — Les indicateurs SymbologyType sont requis | Oui |
| lecture de codes-barres PDF | Non disponible | Oui (natif) |
| Lectures concurrentes sécurisées pour les threads | Non | Oui |
| Lecture par lots (intégrée) | Non | Oui |
| Contrôle de correction d'erreur QR | Non disponible | Oui |
| API statique (sans instance) | Non | Oui |
| Abonnement à la Suite requis | Oui (Infragistics Ultimate, 2 399 $ +/an) | Non |
| Licence perpétuelle | Non | Oui — à partir de 749 $ |
Principaux avantages après la migration
Lecture de code-barres dans WinForms. Si la migration a été motivée par un besoin de lecture dans WinForms, voici le résultat principal : BarcodeReader.Read(imagePath) compile et s'exécute dans WinForms sans configuration supplémentaire.
Prise en charge d' ASP.NET Coreet de la console. Les API Web, les services en arrière-plan et les outils de console peuvent désormais générer et lire des codes-barres à l'aide du même package. Si vous utilisiez des chaînes d'outils distinctes ou des solutions de contournement pour ces types de projets, elles ont disparu.
Aucun modèle de gestionnaire d'événements. Le gestionnaire DecodeComplete, le pont TaskCompletionSource, le chargement BitmapImage et le nettoyage Dispose() sont tous supprimés. Il ne reste plus que la logique des codes-barres.
Aucune spécification de symbologie. Les formats qui échouaient silencieusement en raison de l'absence de drapeaux SymbologyType seront désormais détectés correctement. La détection automatique couvre plus de 50 formats sans configuration.
Même classe de service pour tous les types de projets. Un wrapper BarcodeService unique utilisant BarcodeReader.Read() et BarcodeWriter.CreateBarcode() peut être partagé entre WinForms, WPF, ASP.NET Core, et tout autre projet dans la solution. Aucune implémentation spécifique à un framework.
L'abonnement InfragisticsUltimate n'est pas requis pour la seule fonctionnalité de codes-barres. Si la prise en charge des codes-barres était la seule raison de votre abonnement InfragisticsUltimate, ou si elle a constitué un facteur important dans votre décision, Code-barres IronBarcode est un logiciel autonome avec des options de licence perpétuelle à partir de 749 $ pour un développeur.
La migration en elle-même est mécanique une fois que vous avez localisé toute l'utilisation des codes-barres Infragistics. La partie la plus compliquée est le remplacement de la classe de service WPF, et même cela se résume à supprimer la classe et à remplacer les appels par BarcodeReader.Read(). La migration de génération consiste en un renommage un-à-un des propriétés/méthodes. Vous obtenez ainsi une API unique et cohérente, compatible avec tous les types de projets dont vous avez besoin.

Curtis Chau détient un baccalauréat en informatique (Université de Carleton) et se spécialise dans le développement front-end avec expertise en Node.js, TypeScript, JavaScript et React. Passionné par la création d'interfaces utilisateur intuitives et esthétiquement plaisantes, Curtis aime travailler avec des frameworks modernes et créer des manuels bien structurés et visuellement attrayants.