Un patrón adecuado para una utilidad de importación que tal vez necesite extender en el futuro sería usar MEF: puede mantener el uso de memoria bajo cargando el convertidor que necesita sobre la marcha de una lista lenta, cree importaciones de MEF que sean decorado con atributos que ayudan a seleccionar el convertidor correcto para la importación que está intentando realizar y proporciona una manera fácil de separar las diferentes clases de importación.
Cada parte del MEF puede construirse para satisfacer una interfaz de importación con algunos métodos estándar que convierten una fila del archivo de importación en sus datos de salida o anulan una clase base con la funcionalidad básica.
MEF es un marco para crear una arquitectura de plug-in: es cómo se construyen Outlook y Visual Studio, todas esas hermosas extensiones en VS son partes de MEF.
Para crear una aplicación MEF (Managed Extensability Framework), comience por incluir una referencia a System.ComponentModel.Composition
Defina interfaces para especificar qué hará el convertidor
public interface IImportConverter
{
int UserId { set; }
bool Validate(byte[] fileData, string fileName, ImportType importType);
ImportResult ImportData(byte[] fileData, string fileName, ImportType importType);
}
Esto se puede utilizar para todos los tipos de archivos que desea importar.
Agregue atributos a una nueva clase que defina lo que la clase "Exportará"
[Export(typeof(IImportConverter))]
[MyImport(ImportType.Address, ImportFileType.CSV, "4eca4a5f-74e0")]
public class ImportCSVFormat1 : ImportCSV, IImportConverter
{
...interface methods...
}
Esto definiría una clase que importará archivos CSV (de un formato particular: Formato1) y tiene atributos personalizados que establecen los Metadatos de atributos de exportación de MEF. Repetirías esto para cada formato o tipo de archivo que quieras importar. Puede establecer atributos personalizados con una clase como:
[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; }
}
Para utilizar realmente los convertidores de MEF, necesita importar las partes de MEF que crea cuando se ejecuta el código de conversión:
[ImportMany(AllowRecomposition = true)]
protected internal Lazy<IImportConverter, IImportMetadata>[] converters { get; set; }
AggregateCatalog catalog = new AggregateCatalog();
catalog
recolecta las partes de una carpeta, la ubicación predeterminada de la aplicación es
converters
es una lista lenta de las partes importadas del MEF
Luego, cuando sepa qué tipo de archivo desea convertir ( importFileType
y importType
) obtenga un convertidor de la lista de piezas importadas en 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 llamada a converter.ImportData
usará el código en la clase importada.
Puede parecer una gran cantidad de código y puede llevarle un poco de tiempo lo que está pasando, pero es extremadamente flexible cuando se trata de agregar nuevos tipos de convertidores e incluso puede permitirle agregar nuevos durante el tiempo de ejecución.