Использовать Inversion of Control (Dependency Injection) без сторонних фреймворков при использовании быстро декодируемого протокола? - PullRequest
0 голосов
/ 06 апреля 2020

Как я уже упоминал в вопросе, я не ищу стороннюю структуру внедрения зависимостей, такую ​​как ( Dip ), в качестве решения

Предпосылки и мое понимание:

Без третьей стороны я знаю 3 типа внедрения зависимостей,

Если у меня есть настройка, подобная

protocol DependencyProtocol {

}

class DependencyClass: DependencyProtocol {

}

1. Внедрение в init или constructor

может быть простым:

class SomeClass {
    private let dependency: DependencyProtocol

    init(with dependency: DependencyProtocol) {
        self.dependency = dependency
    }
}

2. Инжектор свойств:

Это может быть просто

class SomeClass {
    var dependency: DependencyProtocol!
}

//In coordinator
let abcd = SomeClass()
abcd.dependency = DependencyClass()

3. Инжектор метода

Передача блока или замыкания в качестве аргумента SomeClass.

Все эти подходы прекрасно работают, когда вы не имеете дело с system protocols, например, декодируемым.

Реальная проблема:

У меня есть шлюз функций, а результаты различных элементов функций анализируются и сохраняются в константах c состояния при запуске приложения. Основываясь на значении этого специфического c признака, я решаю проанализировать указанное поле c в ответ или нет. Я использую Decodable протокол

struct CancellationInfo: Decodable {

}


struct TrackSomething: Decodable {
    let cancellationInfo: CancellationInfo?


    private enum CodingKeys: String, CodingKey {
        case cancellationInfo
    }

     init(from decoder: Decoder) throws {
        if SomeStaticClass.isFeatureEnabled("Cancellation") {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            cancellationInfo = try values.decodeIfPresent(CancellationInfo.self, forKey: .cancellationInfo)
        }
     }
}

Как я буду использовать здесь инверсию управления? Как я буду динамически вводить SomeStaticClass здесь? У меня не может быть собственного собственного init, потому что эта структура используется нашей внутренней сетевой структурой, которая просто вызывает

let reponseData = try? JSONDecoder().decode(S.self, from: data)

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

Не могу придумать любой другой обходной путь, любая помощь в правильном направлении будет оценена :)

...