using IronPdf;
// Disable local disk access or cross-origin requests
Installation.EnableWebSecurity = true;
// Instantiate Renderer
var renderer = new ChromePdfRenderer();
// Create a PDF from a HTML string using C#
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
// Export to a file or Stream
pdf.SaveAs("output.pdf");
// Advanced Example with HTML Assets
// Load external html assets: Images, CSS and JavaScript.
// An optional BasePath 'C:\site\assets\' is set as the file location to load assets from
var myAdvancedPdf = renderer.RenderHtmlAsPdf("<img src='icons/iron.png'>", @"C:\site\assets\");
myAdvancedPdf.SaveAs("html-with-assets.pdf");
Autofac .NET 6 (Comment ça marche pour les développeurs)
Chaknith Bin
juillet 1, 2024
Partager:
Dans le domaine du développement .NET, la gestion efficace des dépendances est cruciale pour créer des applications évolutives, faciles à maintenir et à tester. Les conteneurs d'injection de dépendances (DI) jouent un rôle essentiel dans la réalisation de ces objectifs en facilitant le principe de l'inversion de contrôle (IoC). Parmi la pléthore de bibliothèques de mécanismes d'hébergement génériques disponibles, Autofac se distingue comme un cadre riche en fonctionnalités et extensible pour .NET.
Dans cet article, nous allons partir à la découverte d'Autofac .NET 6, en décortiquant ses caractéristiques et ses avantages pour présenter des exemples pratiques de son utilisation. Plus loin dans cet article, nous découvrirons IronPDF, une puissante bibliothèque de génération de PDF proposée par Iron Software. Nous présenterons également un cas d'utilisation où Autofac.NET et IronPDF sont utilisés conjointement.
Comprendre Autofac .NET
Autofac est un conteneur IoC open-source pour .NET qui offre une prise en charge complète de l'injection de dépendances et de l'enregistrement de composants dans des applications telles que les API web. Développé par Nicholas Blumhardt et maintenu par une communauté dévouée, Autofac offre une solution robuste et flexible pour gérer les durées de vie des objets, résoudre les dépendances et composer des composants d'application.
Pour plus d'informations sur la façon dont Autofac améliore vos applications .NET, envisagez d'explorer les ressources fournies par la bibliothèque PDF de .NET d'IronPDF, qui met en évidence des fonctionnalités avancées pour la génération et la manipulation de PDF. Vous pouvez également explorer la bibliothèque de codes-barres .NET d'IronBarcode pour voir des applications pratiques de l'injection de dépendances dans la génération de codes-barres.
Engagez-vous avec des idées supplémentaires et des exemples pratiques utilisant Autofac dans des scénarios réels en visitant la page officielle d'IronSoftware, où vous trouverez une suite complète de produits comme IronOCR et IronXL qui s'intègrent parfaitement avec Autofac et améliorent votre processus de développement .NET.
Caractéristiques d'Autofac
Construction de conteneurs et enregistrement des composants : Vous pouvez construire des conteneurs à l'aide d'Autofac en enregistrant des composants dans la classe de démarrage. Vous pouvez enregistrer des composants à l'aide de lambdas, de types ou d'instances préconstruites.
public class Startup
{
public void ConfigureContainer()
{
var builder = new ContainerBuilder(); // host sub property builder
builder.RegisterInstance(new TaskRepository()).As<ITaskRepository>();
builder.RegisterType<TaskController>();
builder.Register(c => new LogManager(DateTime.Now)).As<ILogger>();
// Scan an assembly for components
builder.RegisterAssemblyTypes(myAssembly).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces();
var container = builder.Build();
}
}
public class Startup
{
public void ConfigureContainer()
{
var builder = new ContainerBuilder(); // host sub property builder
builder.RegisterInstance(new TaskRepository()).As<ITaskRepository>();
builder.RegisterType<TaskController>();
builder.Register(c => new LogManager(DateTime.Now)).As<ILogger>();
// Scan an assembly for components
builder.RegisterAssemblyTypes(myAssembly).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces();
var container = builder.Build();
}
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText $csharpLabel
Dépendances Express : Autofac peut injecter des paramètres de constructeur, gérer l'injection de propriétés et l'injection de méthode.
public class TaskController
{
private ITaskRepository _repository;
private ILogger _logger;
public TaskController(ITaskRepository repository, ILogger logger)
{
this._repository = repository;
this._logger = logger;
}
}
public class TaskController
{
private ITaskRepository _repository;
private ILogger _logger;
public TaskController(ITaskRepository repository, ILogger logger)
{
this._repository = repository;
this._logger = logger;
}
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText $csharpLabel
Système de module flexible : Les modules Autofac trouvent un équilibre entre la configuration XML et les enregistrements basés sur le code. Vous pouvez spécifier des enregistrements complexes dans le code ou modifier le comportement au moment du déploiement à l'aide de XML.
public class CarTransportModule : Module
{
public bool ObeySpeedLimit { get; set; }
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Car>().As<IVehicle>();
if (ObeySpeedLimit)
builder.RegisterType<SaneDriver>().As<IDriver>();
else
builder.RegisterType<CrazyDriver>().As<IDriver>();
}
}
public class CarTransportModule : Module
{
public bool ObeySpeedLimit { get; set; }
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Car>().As<IVehicle>();
if (ObeySpeedLimit)
builder.RegisterType<SaneDriver>().As<IDriver>();
else
builder.RegisterType<CrazyDriver>().As<IDriver>();
}
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText $csharpLabel
Points d'extension simples : Autofac propose des événements d'activation pour personnaliser l'activation ou la libération de composants.
var builder = new ContainerBuilder();
builder.RegisterType<Listener>().As<IListener>().OnActivated(e => e.Instance.StartListening());
builder.RegisterType<Processor>().OnActivating(e => e.Instance.Initialize());
var container = builder.Build();
var builder = new ContainerBuilder();
builder.RegisterType<Listener>().As<IListener>().OnActivated(e => e.Instance.StartListening());
builder.RegisterType<Processor>().OnActivating(e => e.Instance.Initialize());
var container = builder.Build();
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText $csharpLabel
Principales caractéristiques d'Autofac.NET
Enregistrement Flexible des Composants : Autofac permet aux développeurs d'enregistrer des composants en utilisant une variété de techniques d'enregistrement, y compris l'enregistrement manuel, le balayage d'assemblage et l'enregistrement basé sur des attributs. Cette flexibilité permet de contrôler finement l'instanciation et la configuration des composants.
Gestion à Vie : Autofac prend en charge divers portées de durée de vie d'objet, y compris le singleton, l'instance par dépendance, l'instance par portée de durée de vie et l'instance par requête. Ce contrôle granulaire sur la durée de vie des objets assure une utilisation efficace des ressources et prévient les fuites de mémoire dans les applications de longue durée.
Résolution automatique des dépendances : Autofac résout automatiquement les dépendances en fonction des enregistrements de composants enregistrés et de leurs dépendances. Ce câblage automatique simplifie la configuration de graphes d'objets complexes et favorise un couplage lâche entre les composants.
Composition des modules : Autofac permet aux développeurs d'organiser et d'encapsuler les enregistrements de composants à l'aide de modules. Les modules servent de conteneurs logiques pour les enregistrements connexes, ce qui facilite la gestion et la maintenance d'applications à grande échelle comportant plusieurs composants.
Interception et AOP : Autofac offre un support pour l'interception et la programmation orientée aspect (AOP) grâce à son extension d'interception. Grâce à l'interception, les développeurs peuvent appliquer des préoccupations transversales telles que la journalisation, la mise en cache et la sécurité aux composants sans modifier leur mise en œuvre.
Intégration ASP.NET Core et .NET Core : Autofac s'intègre parfaitement avec .NET Core et ASP.NET Core, offrant un support de premier ordre pour l'injection de dépendances dans les applications web modernes et les microservices. Il tire parti de l'abstraction du fournisseur de services intégré pour garantir la compatibilité et l'interopérabilité avec l'écosystème .NET.
Exemples pratiques avec Autofac.NET
Explorons quelques exemples pratiques pour illustrer l'utilisation d'Autofac.NET :
public class Program
{
public static void Main()
{
// Setting up Autofac container
var builder = new ContainerBuilder();
// Registering types manually
builder.RegisterType<MyService>().As<IMyService>();
// Registering types using assembly scanning
builder.RegisterAssemblyTypes(typeof(MyAssembly).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
// Registering modules
builder.RegisterModule(new MyModule());
// Building the container
var container = builder.Build();
// Resolving dependencies
using (var scope = container.BeginLifetimeScope())
{
var service = scope.Resolve<IMyService>();
service.DoSomething();
}
}
}
public class Program
{
public static void Main()
{
// Setting up Autofac container
var builder = new ContainerBuilder();
// Registering types manually
builder.RegisterType<MyService>().As<IMyService>();
// Registering types using assembly scanning
builder.RegisterAssemblyTypes(typeof(MyAssembly).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
// Registering modules
builder.RegisterModule(new MyModule());
// Building the container
var container = builder.Build();
// Resolving dependencies
using (var scope = container.BeginLifetimeScope())
{
var service = scope.Resolve<IMyService>();
service.DoSomething();
}
}
}
Public Class Program
Public Shared Sub Main()
' Setting up Autofac container
Dim builder = New ContainerBuilder()
' Registering types manually
builder.RegisterType(Of MyService)().As(Of IMyService)()
' Registering types using assembly scanning
builder.RegisterAssemblyTypes(GetType(MyAssembly).Assembly).Where(Function(t) t.Name.EndsWith("Repository")).AsImplementedInterfaces()
' Registering modules
builder.RegisterModule(New MyModule())
' Building the container
Dim container = builder.Build()
' Resolving dependencies
Using scope = container.BeginLifetimeScope()
Dim service = scope.Resolve(Of IMyService)()
service.DoSomething()
End Using
End Sub
End Class
$vbLabelText $csharpLabel
Dans cette section, nous avons démontré la mise en œuvre pratique d'Autofac.NET pour l'injection de dépendances. De l'enregistrement manuel à la numérisation de l'assemblage et à l'enregistrement basé sur les modules, nous avons montré la flexibilité qu'offre Autofac dans la gestion des dépendances. En utilisant ces techniques, les développeurs peuvent rationaliser le processus d'injection de dépendances de leur application, améliorant ainsi la maintenabilité et l'évolutivité.
Pour plus d'informations sur la manière dont les produits d'Iron Software peuvent s'intégrer à vos applications .NET pour rationaliser et améliorer davantage la fonctionnalité, explorez la documentation d'IronPDF où vous pouvez apprendre à générer et modifier des documents PDF par programme, ou visitez le site web d'Iron Software pour découvrir une large gamme de puissantes bibliothèques .NET comme IronBarcode pour la lecture et l'écriture de codes-barres, et IronOCR pour la reconnaissance optique de caractères avancée.
Avantages de l'utilisation d'Autofac.NET
Simplicité et Flexibilité : Autofac propose une API simple et intuitive pour l'enregistrement et la résolution des composants, rendant l'injection de dépendances facile à mettre en œuvre et à maintenir.
Testabilité et maintenabilité : En favorisant le découplage et l'inversion des dépendances, Autofac améliore la testabilité et la maintenabilité des applications .NET, permettant ainsi des tests unitaires et un refactoring facilités.
Performance et évolutivité : La légèreté et l'efficacité de l'exécution d'Autofac en font un choix adapté pour les applications à haute performance et les systèmes évolutifs avec de grands graphes d'objets.
Extensibilité et personnalisation : L'architecture extensible d'Autofac permet aux développeurs d'étendre et de personnaliser le comportement d'Autofac grâce à des modules personnalisés, des sources d'enregistrement et des composants middleware, répondant ainsi à des exigences d'application variées.
Communauté et Support: Avec une communauté active de développeurs et une documentation complète, Autofac offre un excellent support et des ressources pour l'apprentissage, le dépannage et la contribution au framework.
Licence Autofac
Autofac est livré avec une licence MIT qui est libre d'utilisation pour le développement et à des fins commerciales.
Présentation d'IronPDF d'Iron Software
IronPDF est une bibliothèque PDF C# robuste conçue pour fournir une solution complète de gestion des PDF dans les projets .NET. Que vos besoins concernent la création, l'édition, l'exportation, la sécurisation, le chargement ou la manipulation de documents PDF, IronPDF possède les outils dont vous avez besoin. Voici quelques-unes de ses caractéristiques et applications les plus remarquables :
Conversion HTML en PDF : Convertissez facilement le contenu HTML en PDF. Générer des PDF à partir de HTML, MVC, ASPX et d'images.
Gestion des PDF : Avec plus de 50 fonctionnalités, IronPDF vous permet de signer, d'éditer et d'extraire du contenu des PDFs, rendant les signatures numériques et les modifications faciles.
Support multiplateforme : Compatible avec C#, F# et VB.NET, IronPDF fonctionne sur différentes versions de .NET, y compris .NET Core, .NET Standard et .NET Framework. Il est également disponible pour Java, Node.js et Python.
Pour en savoir plus sur la façon dont IronPDF peut intégrer des fonctionnalités PDF dans vos projets, visitez la page produit IronPDF.
Pour un aperçu complet des offres de produits d'Iron Software, y compris IronBarcode, IronOCR, et plus, visitez la page d'accueil d'Iron Software.
Compatibilité et environnements
Versions .NET : Prend en charge C#, VB.NET et F#.
Types de projets : Convient pour les applications web (Blazor & WebForms avec IronPDF), de bureau (WPF & MAUI), et console.
Environnements d'application : Compatible avec Windows, Linux, Mac, Docker, Azure, AWS, et plus encore.
using Autofac;
using CacheManager.Core;
using IronPdf;
using System.Reflection;
namespace IronPdfDemos
{
public class AutoFac
{
public static void Execute()
{
// Instantiate Cache and ChromePdfRenderer
var renderer = new ChromePdfRenderer();
var cache = CacheFactory.Build("ironPdfAutofac", settings =>
{
settings.WithDictionaryHandle();
});
// Prepare HTML content
var content = "<h1>Demonstrate Autofac with IronPDF</h1>";
content += "<p>This is an illustration of using Autofac for dependency injection and IronPDF for generating PDF documents.</p>";
content += "<h2>Setting up Autofac container</h2>";
// Setting up Autofac container
var builder = new ContainerBuilder();
content += "<p>var builder = new ContainerBuilder();</p>";
content += "<h2>Registering types manually</h2>";
// Registering types manually
builder.RegisterType<MyService>().As<IMyService>();
content += "<p>builder.RegisterType<MyService>().As<IMyService();</p>";
content += "<h2>Registering types using assembly scanning</h2>";
// Registering types using assembly scanning
builder.RegisterAssemblyTypes(typeof(AutoFac).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
content += "<p>builder.RegisterAssemblyTypes(typeof(AutoFac).Assembly).Where(t => t.Name.EndsWith(\"Repository\")).AsImplementedInterfaces();</p>";
content += "<h2>Registering modules</h2>";
// Registering modules
builder.RegisterModule(new MyModule());
content += "<p>builder.RegisterModule(new MyModule());</p>";
content += "<h2>Building the container</h2>";
// Building the container
var container = builder.Build();
content += "<p>var container = builder.Build();</p>";
content += "<h2>Resolving dependencies</h2>";
// Resolving dependencies
using (var scope = container.BeginLifetimeScope())
{
var service = scope.Resolve<IMyService>();
service.DoSomething();
}
content += "<p>var service = scope.Resolve<IMyService();</p>";
// Create a PDF from the HTML string using C#
var pdf = renderer.RenderHtmlAsPdf(content);
// Export to a file or Stream
pdf.SaveAs("autofac.pdf");
Console.WriteLine("We are done...");
Console.ReadKey();
}
}
internal interface IMyService
{
void DoSomething();
}
internal class MyModule : Module
{
protected override void Load(ContainerBuilder builder)
{
// Register module dependencies here
}
}
internal class MyService : IMyService
{
public void DoSomething()
{
Console.WriteLine("DoSomething");
}
}
}
using Autofac;
using CacheManager.Core;
using IronPdf;
using System.Reflection;
namespace IronPdfDemos
{
public class AutoFac
{
public static void Execute()
{
// Instantiate Cache and ChromePdfRenderer
var renderer = new ChromePdfRenderer();
var cache = CacheFactory.Build("ironPdfAutofac", settings =>
{
settings.WithDictionaryHandle();
});
// Prepare HTML content
var content = "<h1>Demonstrate Autofac with IronPDF</h1>";
content += "<p>This is an illustration of using Autofac for dependency injection and IronPDF for generating PDF documents.</p>";
content += "<h2>Setting up Autofac container</h2>";
// Setting up Autofac container
var builder = new ContainerBuilder();
content += "<p>var builder = new ContainerBuilder();</p>";
content += "<h2>Registering types manually</h2>";
// Registering types manually
builder.RegisterType<MyService>().As<IMyService>();
content += "<p>builder.RegisterType<MyService>().As<IMyService();</p>";
content += "<h2>Registering types using assembly scanning</h2>";
// Registering types using assembly scanning
builder.RegisterAssemblyTypes(typeof(AutoFac).Assembly)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
content += "<p>builder.RegisterAssemblyTypes(typeof(AutoFac).Assembly).Where(t => t.Name.EndsWith(\"Repository\")).AsImplementedInterfaces();</p>";
content += "<h2>Registering modules</h2>";
// Registering modules
builder.RegisterModule(new MyModule());
content += "<p>builder.RegisterModule(new MyModule());</p>";
content += "<h2>Building the container</h2>";
// Building the container
var container = builder.Build();
content += "<p>var container = builder.Build();</p>";
content += "<h2>Resolving dependencies</h2>";
// Resolving dependencies
using (var scope = container.BeginLifetimeScope())
{
var service = scope.Resolve<IMyService>();
service.DoSomething();
}
content += "<p>var service = scope.Resolve<IMyService();</p>";
// Create a PDF from the HTML string using C#
var pdf = renderer.RenderHtmlAsPdf(content);
// Export to a file or Stream
pdf.SaveAs("autofac.pdf");
Console.WriteLine("We are done...");
Console.ReadKey();
}
}
internal interface IMyService
{
void DoSomething();
}
internal class MyModule : Module
{
protected override void Load(ContainerBuilder builder)
{
// Register module dependencies here
}
}
internal class MyService : IMyService
{
public void DoSomething()
{
Console.WriteLine("DoSomething");
}
}
}
Imports Autofac
Imports CacheManager.Core
Imports IronPdf
Imports System.Reflection
Namespace IronPdfDemos
Public Class AutoFac
Public Shared Sub Execute()
' Instantiate Cache and ChromePdfRenderer
Dim renderer = New ChromePdfRenderer()
Dim cache = CacheFactory.Build("ironPdfAutofac", Sub(settings)
settings.WithDictionaryHandle()
End Sub)
' Prepare HTML content
Dim content = "<h1>Demonstrate Autofac with IronPDF</h1>"
content &= "<p>This is an illustration of using Autofac for dependency injection and IronPDF for generating PDF documents.</p>"
content &= "<h2>Setting up Autofac container</h2>"
' Setting up Autofac container
Dim builder = New ContainerBuilder()
content &= "<p>var builder = new ContainerBuilder();</p>"
content &= "<h2>Registering types manually</h2>"
' Registering types manually
builder.RegisterType(Of MyService)().As(Of IMyService)()
content &= "<p>builder.RegisterType<MyService>().As<IMyService();</p>"
content &= "<h2>Registering types using assembly scanning</h2>"
' Registering types using assembly scanning
builder.RegisterAssemblyTypes(GetType(AutoFac).Assembly).Where(Function(t) t.Name.EndsWith("Repository")).AsImplementedInterfaces()
content &= "<p>builder.RegisterAssemblyTypes(typeof(AutoFac).Assembly).Where(t => t.Name.EndsWith(""Repository"")).AsImplementedInterfaces();</p>"
content &= "<h2>Registering modules</h2>"
' Registering modules
builder.RegisterModule(New MyModule())
content &= "<p>builder.RegisterModule(new MyModule());</p>"
content &= "<h2>Building the container</h2>"
' Building the container
Dim container = builder.Build()
content &= "<p>var container = builder.Build();</p>"
content &= "<h2>Resolving dependencies</h2>"
' Resolving dependencies
Using scope = container.BeginLifetimeScope()
Dim service = scope.Resolve(Of IMyService)()
service.DoSomething()
End Using
content &= "<p>var service = scope.Resolve<IMyService();</p>"
' Create a PDF from the HTML string using C#
Dim pdf = renderer.RenderHtmlAsPdf(content)
' Export to a file or Stream
pdf.SaveAs("autofac.pdf")
Console.WriteLine("We are done...")
Console.ReadKey()
End Sub
End Class
Friend Interface IMyService
Sub DoSomething()
End Interface
Friend Class MyModule
Inherits Module
Protected Overrides Sub Load(ByVal builder As ContainerBuilder)
' Register module dependencies here
End Sub
End Class
Friend Class MyService
Implements IMyService
Public Sub DoSomething() Implements IMyService.DoSomething
Console.WriteLine("DoSomething")
End Sub
End Class
End Namespace
$vbLabelText $csharpLabel
Explication du code
Décortiquons l'extrait de code que vous avez fourni :
Configuration de ChromePdfRenderer :
Le code initialise une instance de ChromePdfRenderer pour générer des PDF à partir de contenu HTML, une caractéristique clé de IronPDF.
Préparation du contenu HTML :
La variable content est une chaîne HTML qui sera utilisée pour générer le PDF.
Il inclut une balise <h1> avec le titre "Démontrer Autofac avec IronPDF".
Configuration du conteneur Autofac :
Le code crée une instance de ContainerBuilder nommée builder.
C'est la première étape de la mise en place d'un conteneur Autofac pour l'injection de dépendances.
Enregistrement manuel des types :
Il enregistre un type MyService comme une implémentation de l'interface IMyService.
Cela permet à Autofac de résoudre les dépendances si nécessaire.
Enregistrement des types à l'aide de la numérisation d'assembly :
Il scanne l'assembly contenant le type AutoFac.
Enregistre les types dont les noms se terminent par "Repository" en tant qu'implémentations de leurs interfaces correspondantes.
Enregistrement des modules :
Il enregistre un module appelé MyModule.
Les modules permettent de regrouper des enregistrements connexes.
Construction du conteneur :
Le conteneur est construit à partir des composants enregistrés en utilisant la méthode builder.Build().
Résolution des dépendances :
À l'intérieur d'une portée de durée de vie (using (var scope = container.BeginLifetimeScope())), il résout une instance de IMyService.
La méthode DoSomething est appelée sur le service résolu.
Génération de PDF :
Un PDF est créé à partir du contenu en utilisant le ChromePdfRenderer.
Le PDF résultant est enregistré sous le nom de "autofac.pdf".
Sortie
Licence d'IronPDF
IronPDF nécessite une clé de licence. Placez la clé de licence dans le fichier appSettings.json comme indiqué ci-dessous.
Chaknith travaille sur IronXL et IronBarcode. Il possède une expertise approfondie en C# et .NET, aidant à améliorer le logiciel et à soutenir les clients. Ses idées issues des interactions avec les utilisateurs contribuent à de meilleurs produits, une documentation améliorée et une expérience globale enrichie.
< PRÉCÉDENT OpenTelemetry .NET (Comment ça marche pour les développeurs)
SUIVANT > Papercut SMTP C# (Comment ça marche pour les développeurs)
Des millions d'ingénieurs dans le monde entier lui font confiance
Réservez une démo en direct gratuite
Réservez une démonstration personnelle de 30 minutes.
Pas de contrat, pas de détails de carte, pas d'engagements.
Voici ce à quoi vous pouvez vous attendre :
Une démonstration en direct de notre produit et de ses principales fonctionnalités
Obtenez des recommandations de fonctionnalités spécifiques au projet
Toutes vos questions trouvent réponse pour vous assurer de disposer de toutes les informations dont vous avez besoin. (Aucun engagement de votre part.)
CHOISIR L'HEURE
VOS INFORMATIONS
Réservez votre démo en direct gratuite
Fiable par plus de 2 millions d'ingénieurs dans le monde entier