Существуют ли какие-либо шаблоны для управления версиями компонентов и обратной совместимости с использованием Windsor? - PullRequest
1 голос
/ 16 августа 2010

Я должен поддерживать новый формат входного файла в системе, которая использует Windsor. Мне также нужно поддерживать старую версию входного файла на этапе перехода. Это, вероятно, будет повторяться в будущем, и нам снова нужно будет поддерживать новый и следующий самый последний формат.

Обработка импорта выполняется компонентом, и новая версия значительно улучшила код, что делает его намного более эффективным по сравнению со старой версией. Поэтому я хотел бы иметь новый компонент и старый компонент в системе и динамически использовать новый или старый компонент на основе метаданных файла.

Есть ли образец для такого типа сценария, который кто-нибудь может предложить?

1 Ответ

2 голосов
/ 16 августа 2010

То, что вы используете Виндзор, здесь в значительной степени не имеет значения. Всегда стремитесь найти независимое от контейнера решение. Вот один из них:

interface IImportProcessor {
    bool CanHandleVersion(int version);
    Stream Import(Stream input);
}

class ImportProcessorVersion1 : IImportProcessor {
    public bool CanHandleVersion(int version) {
        return version == 1;
    }

    public Stream Import(Stream input) {
        // do stuff
        return input;
    }
}

class ImportProcessorVersion2 : IImportProcessor {
    public bool CanHandleVersion(int version) {
        return version == 2;
    }

    public Stream Import(Stream input) {
        // do stuff
        return input;
    }
}

class MainImportProcessor: IImportProcessor {
    private readonly IImportProcessor[] versionSpecificProcessors;

    public MainImportProcessor(IImportProcessor[] versionSpecificProcessors) {
        this.versionSpecificProcessors = versionSpecificProcessors;
    }

    public bool CanHandleVersion(int version) {
        return versionSpecificProcessors.Any(p => p.CanHandleVersion(version));
    }

    private int FetchVersion(Stream input) {
        // do stuff
        return 1;
    }

    public Stream Import(Stream input) {
        int version = FetchVersion(input);
        var processor = versionSpecificProcessors.FirstOrDefault(p => p.CanHandleVersion(version));
        if (processor == null)
            throw new Exception("Unsupported version " + version);
        return processor.Import(input);
    }
}

Ваше приложение будет зависеть от IImportProcessor. Контейнер подключен так, что реализация этого интерфейса по умолчанию - MainImportProcessor. Контейнер также подключен так, что MainImportProcessor получает всех других реализаций из IImportProcessor. Таким образом, вы можете добавить реализации IImportProcessor, и каждая из них будет выбрана в случае необходимости.

Возможно, было бы проще соединить вещи, если MainImportProcessor реализует интерфейс, отличный от IImportProcessor.

Другой возможностью может быть внедрение цепочки ответственности .

...