Un patrón adecuado para una utilidad de importación que puede necesitar extender en el futuro sería usar MEF: puede mantener bajo el uso de memoria cargando el convertidor que necesita sobre la marcha desde una lista perezosa, crear importaciones MEF decoradas con atributos que ayudan a seleccionar el convertidor adecuado para la importación que está intentando realizar y proporciona una manera fácil de separar las diferentes clases de importación.
Cada parte MEF se puede construir para satisfacer una interfaz de importación con algunos métodos estándar que convierten una fila del archivo de importación a sus datos de salida o anulan una clase base con la funcionalidad básica.
MEF es un marco para crear una arquitectura de complemento: es cómo se construyen Outlook y Visual Studio, todas esas extensiones encantadoras 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 usar 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: Format1) y tiene atributos personalizados que configuran Metadatos de atributos de exportación MEF. Repita esto para cada formato o tipo de archivo que desee 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 usar realmente los convertidores MEF, debe importar las partes MEF que crea cuando se ejecuta su código de conversión:
[ImportMany(AllowRecomposition = true)]
protected internal Lazy<IImportConverter, IImportMetadata>[] converters { get; set; }
AggregateCatalog catalog = new AggregateCatalog();
catalog recopila las partes de una carpeta, el valor predeterminado es la ubicación de la aplicación.
converters es una lista perezosa de las partes MEF importadas
Luego, cuando sepa qué tipo de archivo desea convertir ( importFileTypey importType) obtenga un convertidor de la lista de partes importadas enconverters
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.ImportDatautilizará el código en la clase importada.
Puede parecer una gran cantidad de código y puede llevar un tiempo entender qué está pasando, pero es extremadamente flexible cuando se trata de agregar nuevos tipos de convertidor e incluso puede permitirle agregar nuevos durante el tiempo de ejecución.