Un modello adatto per un'utilità di importazione che potrebbe essere necessario estendere in futuro sarebbe utilizzare MEF - puoi mantenere basso l'uso della memoria caricando il convertitore necessario al volo da una lista pigra, creare importazioni MEF che sono decorato con attributi che aiutano a selezionare il convertitore giusto per l'importazione che stai cercando di eseguire e fornisce un modo semplice per separare le diverse classi di importazione.
Ogni parte MEF può essere costruita per soddisfare un'interfaccia di importazione con alcuni metodi standard che convertono una riga del file di importazione nei dati di output o sovrascrivono una classe base con la funzionalità di base.
MEF è un framework per la creazione di un'architettura plug-in - il modo in cui Outlook e Visual Studio sono costruiti, tutte quelle deliziose estensioni in VS sono parti MEF.
Per creare un'app per MEF (Managed Extensability Framework), includi un riferimento a System.ComponentModel.Composition
Definisci interfacce per spec out su cosa farà il convertitore
public interface IImportConverter
{
int UserId { set; }
bool Validate(byte[] fileData, string fileName, ImportType importType);
ImportResult ImportData(byte[] fileData, string fileName, ImportType importType);
}
Può essere usato per tutti i tipi di file che vuoi importare.
Aggiungi attributi a una nuova classe che definiscono ciò che la classe "Esporta"
[Export(typeof(IImportConverter))]
[MyImport(ImportType.Address, ImportFileType.CSV, "4eca4a5f-74e0")]
public class ImportCSVFormat1 : ImportCSV, IImportConverter
{
...interface methods...
}
Questo definirà una classe che importerà i file CSV (di un particolare formato: Format1) e ha degli attributi personalizzati che impostano i metadati degli attributi di esportazione MEF. Lo ripeteresti per ogni formato o tipo di file che desideri importare. Puoi impostare attributi personalizzati con una classe come:
[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; }
}
Per utilizzare effettivamente i convertitori MEF è necessario importare le parti MEF che crei quando viene eseguito il codice di conversione:
[ImportMany(AllowRecomposition = true)]
protected internal Lazy<IImportConverter, IImportMetadata>[] converters { get; set; }
AggregateCatalog catalog = new AggregateCatalog();
catalog
raccoglie le parti da una cartella, il valore predefinito è la posizione dell'app.
converters
è un elenco pigro delle parti MEF importate
Quindi quando sai quale tipo di file vuoi convertire ( importFileType
e importType
) ottieni un convertitore dall'elenco delle parti importate in converters
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);
....
}
La chiamata a converter.ImportData
utilizzerà il codice nella classe importata.
Potrebbe sembrare un sacco di codice e potrebbe volerci un po 'di tempo per capire cosa sta succedendo, ma è estremamente flessibile quando si tratta di aggiungere nuovi tipi di convertitore e può persino permetterti di aggiungerne di nuovi durante il runtime.