Підходящою схемою для утиліти, що імпортує, яку, можливо, вам потрібно буде розширити в майбутньому, було б використовувати MEF - ви можете зберегти низьке використання пам’яті, завантажуючи потрібний перетворювач на льоту з ледачого списку, створювати імпорт MEF, прикрашений атрибутами які допомагають вибрати потрібний перетворювач для імпорту, який ви намагаєтеся виконати, і забезпечує простий спосіб відокремити різні класи імпорту.
Кожна частина MEF може бути побудована так, щоб задовольнити інтерфейс імпорту за допомогою деяких стандартних методів, які перетворюють рядок файлу імпорту у вихідні дані або замінюють базовий клас з базовою функціональністю.
MEF - це основа для створення архітектури плагінів - як будуються перспективи та Visual Studio, всі ці чудові розширення в VS є частиною MEF.
Щоб створити програму MEF (Managed Framework Extensability Framework), почніть з включення посилання на System.ComponentModel.Composition
Визначте інтерфейси, щоб визначити, що буде робити перетворювач
public interface IImportConverter
{
int UserId { set; }
bool Validate(byte[] fileData, string fileName, ImportType importType);
ImportResult ImportData(byte[] fileData, string fileName, ImportType importType);
}
Це можна використовувати для всіх типів файлів, які ви хочете імпортувати.
Додайте атрибути до нового класу, які визначають, який клас буде "Експортувати"
[Export(typeof(IImportConverter))]
[MyImport(ImportType.Address, ImportFileType.CSV, "4eca4a5f-74e0")]
public class ImportCSVFormat1 : ImportCSV, IImportConverter
{
...interface methods...
}
Це визначило б клас, який імпортуватиме файли CSV (певного формату: Format1) та має власні атрибути, що встановлюють метадані експортних атрибутів MEF. Ви повторите це для кожного формату або типу файлу, який потрібно імпортувати. Ви можете встановити власні атрибути з таким класом, як:
[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; }
}
Для того, щоб фактично використовувати перетворювачі MEF, вам потрібно імпортувати деталі MEF, які ви створюєте під час запуску коду перетворення:
[ImportMany(AllowRecomposition = true)]
protected internal Lazy<IImportConverter, IImportMetadata>[] converters { get; set; }
AggregateCatalog catalog = new AggregateCatalog();
catalog
збирає частини з папки, за замовчуванням - місце розташування програми.
converters
- лінивий список імпортованих деталей MEF
Тоді, коли ви знаєте, який тип файлу ви хочете перетворити ( importFileType
і importType
), отримайте конвертер зі списку імпортованих частин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);
....
}
Заклик до converter.ImportData
буде використовувати код у імпортованому класі.
Можливо, це виглядає як багато коду, і це може зайняти деякий час, щоб обернутися тим, що відбувається, але його надзвичайно гнучко, якщо мова йде про додавання нових типів перетворювачів і навіть може дозволити вам додавати нові під час виконання.