Un modèle approprié pour un utilitaire d'importation que vous devrez peut-être étendre à l'avenir serait d'utiliser MEF - vous pouvez réduire l'utilisation de la mémoire en chargeant le convertisseur dont vous avez besoin à la volée à partir d'une liste paresseuse, créer des importations MEF décorées d'attributs qui aident à sélectionner le bon convertisseur pour l'importation que vous essayez d'effectuer et fournit un moyen facile de séparer les différentes classes d'importation.
Chaque partie MEF peut être construite pour satisfaire une interface d'importation avec certaines méthodes standard qui convertissent une ligne du fichier d'importation en vos données de sortie ou remplacent une classe de base avec la fonctionnalité de base.
MEF est un cadre pour créer une architecture de plug-in - sa façon dont Outlook et Visual Studio sont construits, toutes ces belles extensions dans VS sont des parties MEF.
Pour créer une application MEF (Managed Extensability Framework), commencez par inclure une référence à System.ComponentModel.Composition
Définir des interfaces pour spécifier ce que fera le convertisseur
public interface IImportConverter
{
int UserId { set; }
bool Validate(byte[] fileData, string fileName, ImportType importType);
ImportResult ImportData(byte[] fileData, string fileName, ImportType importType);
}
Cela peut être utilisé pour tous les types de fichiers que vous souhaitez importer.
Ajouter des attributs à une nouvelle classe qui définissent ce que la classe "exportera"
[Export(typeof(IImportConverter))]
[MyImport(ImportType.Address, ImportFileType.CSV, "4eca4a5f-74e0")]
public class ImportCSVFormat1 : ImportCSV, IImportConverter
{
...interface methods...
}
Cela définirait une classe qui importera des fichiers CSV (d'un format particulier: Format1) et possède des attributs personnalisés qui définissent les métadonnées d'attribut d'exportation MEF. Vous répéteriez cela pour chaque format ou type de fichier que vous souhaitez importer. Vous pouvez définir des attributs personnalisés avec une classe comme:
[MetadataAttribute]
[AttributeUsage(AttributeTargets.All, AllowMultiple = false)]
public class ImportAttribute : ExportAttribute
{
public ImportAttribute(ImportType importType, ImportFileType fileType, string customerUID)
: base(typeof(IImportConverter))
{
ImportType = importType;
FileType = fileType;
CustomerUID = customerUID;
}
public ImportType ImportType { get; set; }
public ImportFileType FileType { get; set; }
public string CustomerUID { get; set; }
}
Pour utiliser réellement les convertisseurs MEF, vous devez importer les pièces MEF que vous créez lors de l'exécution de votre code de conversion:
[ImportMany(AllowRecomposition = true)]
protected internal Lazy<IImportConverter, IImportMetadata>[] converters { get; set; }
AggregateCatalog catalog = new AggregateCatalog();
catalog
recueille les pièces d'un dossier, par défaut est l'emplacement de l'application.
converters
est une liste paresseuse des pièces MEF importées
Ensuite, lorsque vous savez quel type de fichier vous souhaitez convertir ( importFileType
et importType
) obtenez un convertisseur à partir de la liste des pièces importées dansconverters
var tmpConverter = (from x in converters
where x.Metadata.FileType == importFileType
&& x.Metadata.ImportType == importType
&& (x.Metadata.CustomerUID == import.ImportDataCustomer.CustomerUID)
select x).OrderByDescending(x => x.Metadata.CustomerUID).FirstOrDefault();
if (tmpConverter != null)
{
var converter = (IImportConverter)tmpConverter.Value;
result = converter.ImportData(import.ImportDataFile, import.ImportDataFileName, importType);
....
}
L'appel à converter.ImportData
utilisera le code dans la classe importée.
Cela peut sembler beaucoup de code et cela peut prendre un certain temps pour comprendre ce qui se passe, mais c'est extrêmement flexible quand il s'agit d'ajouter de nouveaux types de convertisseurs et peut même vous permettre d'en ajouter de nouveaux pendant l'exécution.