Swift: шаблон фабрики, попробуйте создать экземпляр объекта только один раз, доступный из всех контроллеров - PullRequest
6 голосов
/ 16 мая 2019

Я написал фабричный шаблон (который выглядит как внедрение зависимостей), который отлично работает:

protocol Dependency {
    func resolveExtractIcon() -> ExtractIconService
}

class DependencyFactory: Dependency, HasDependencies {

    func resolveExtractIcon() -> ExtractIconService {
        return ExtractIcon()
    }

}


struct DependencyInjector {
    static var dependencies: Dependency = DependencyFactory()

    private init() {}
}

protocol HasDependencies {
    var dependencies: Dependency { get }
}

extension HasDependencies {
    var dependencies: Dependency {
        return DependencyInjector.dependencies
    }
}

В моем контроллере View я могу назвать его так:

class IOSAssetsViewController: NSViewController, HasDependencies {
    private lazy var assetsViewModel: AssetsViewModelService = dependencies.resolveExtractIcon()
}

Теперь я хотел бы добавить в этот шаблон проектирования возможность создать объект один раз и внедрить его в нужный мне контроллер вида.

Например, у меня есть viewModel, связанная с тремя контроллерами представления в моем проекте, яхочу, чтобы, когда я изменял viewModel в ViewController, в то время как они изменяются везде, потому что они используют один и тот же экземпляр, даже если ViewController не существует сразу после его создания, он будет использовать внедренный viewModel с изменениями, сделанными другими контроллерами представления.

Я перепробовал множество возможностей, и мне удалось убедиться, что только контроллеры представлений создают в то же время доступ к одному и тому же экземпляру, но еще не существовавшие контроллеры, для которых это былосоздать затем он обращается к новому объекту, а не объект изменилсяпод редакцией контроллера представления:

 class DependencyFactory: Dependency, HasDependencies {

    // Below it has allowed me to create a single instance accessible only to the view controller create at the same time
    let resoledAssetsViewModel: AssetsViewModelService = AssetsViewModel(extractIconManager: ExtractIcon())

    func resolveExtractIcon() -> ExtractIconService {
        return ExtractIcon()
    }

}

Как я могу создать этот шаблон проектирования для создания одного экземпляра для viewmModel, внедренного в viewController?

Как будто я создаю viewModel в appdelegate,и все мои контроллеры вызывают через AppDelegate и модифицируют его.Но я не хочу делать это через делегата приложения, это не красиво, и это не очень хорошая практика.Я хочу делать то, что хочу, следуя моему заводскому шаблону

Спасибо за вашу помощь:)

...