Một mô hình phù hợp cho một tiện ích nhập khẩu mà bạn có thể cần mở rộng trong tương lai sẽ là sử dụng MEF - bạn có thể giữ mức sử dụng bộ nhớ thấp bằng cách tải bộ chuyển đổi bạn cần từ danh sách lười biếng, tạo các bản nhập MEF được trang trí bằng các thuộc tính giúp chọn trình chuyển đổi phù hợp cho quá trình nhập mà bạn đang cố thực hiện và cung cấp một cách dễ dàng để tách các lớp nhập khác nhau ra.
Mỗi phần MEF có thể được xây dựng để đáp ứng giao diện nhập với một số phương thức tiêu chuẩn chuyển đổi một hàng của tệp nhập thành dữ liệu đầu ra của bạn hoặc ghi đè một lớp cơ sở với chức năng cơ bản.
MEF là một khung để tạo kiến trúc trình cắm - cách xây dựng triển vọng và Visual Studio, tất cả các tiện ích mở rộng đáng yêu trong VS đều là các phần MEF.
Để xây dựng ứng dụng MEF (Khung mở rộng được quản lý) bắt đầu bằng việc bao gồm một tham chiếu đến System.ComponentModel.Composition
Xác định giao diện để chỉ ra những gì trình chuyển đổi sẽ làm
public interface IImportConverter
{
int UserId { set; }
bool Validate(byte[] fileData, string fileName, ImportType importType);
ImportResult ImportData(byte[] fileData, string fileName, ImportType importType);
}
Điều này có thể được sử dụng cho tất cả các loại tệp bạn muốn nhập.
Thêm thuộc tính cho một lớp mới xác định lớp sẽ "Xuất"
[Export(typeof(IImportConverter))]
[MyImport(ImportType.Address, ImportFileType.CSV, "4eca4a5f-74e0")]
public class ImportCSVFormat1 : ImportCSV, IImportConverter
{
...interface methods...
}
Điều này sẽ xác định một lớp sẽ nhập tệp CSV (có định dạng cụ thể: Format1) và có các thuộc tính tùy chỉnh đặt Siêu dữ liệu thuộc tính xuất MEF. Bạn sẽ lặp lại điều này cho từng định dạng hoặc loại tệp bạn muốn nhập. Bạn có thể đặt thuộc tính tùy chỉnh với một lớp như:
[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; }
}
Để thực sự sử dụng bộ chuyển đổi MEF, bạn cần nhập các phần MEF bạn tạo khi mã chuyển đổi của bạn được chạy:
[ImportMany(AllowRecomposition = true)]
protected internal Lazy<IImportConverter, IImportMetadata>[] converters { get; set; }
AggregateCatalog catalog = new AggregateCatalog();
catalog
thu thập các phần từ một thư mục, mặc định là vị trí ứng dụng.
converters
là một danh sách lười biếng của các bộ phận MEF nhập khẩu
Sau đó, khi bạn biết loại tệp nào bạn muốn chuyển đổi ( importFileType
và importType
) có được trình chuyển đổi từ danh sách các phần được nhập trongconverters
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);
....
}
Cuộc gọi đến converter.ImportData
sẽ sử dụng mã trong lớp đã nhập.
Có thể có rất nhiều mã và có thể mất một lúc để bạn hiểu được những gì đang diễn ra nhưng nó cực kỳ linh hoạt khi thêm các loại trình chuyển đổi mới và thậm chí có thể cho phép bạn thêm các mã mới trong thời gian chạy.