Skip to content

Releases: rockbruno/RouterService

1.1.0

12 Aug 15:00
Compare
Choose a tag to compare

1.0.0 - Property Wrappers

12 Aug 14:15
73ee81d
Compare
Choose a tag to compare
  • Removed AnyDependenciesInitializer
  • Removed AnyFeature
  • Remove the Dependency protocol
  • Added the @Dependency property wrapper

The ugly boilerplate of this framework like AnyFeature and AnyDependenciesInitializer are a result of the Swift compiler's limitation on generics. In this PR, I tested the creation of features using property wrappers instead of the usual dependencies struct. It worked, and by using Mirror to resolve the properties, I am able to drop the associated type from the Feature and all other ugly type-erasures alongside it :)

Here's how features looked before this change:

private enum ProfileFeature: Feature {
    struct Dependencies {
        let client: HTTPClientProtocol
    }

    static var dependenciesInitializer: AnyDependenciesInitializer {
        return AnyDependenciesInitializer(Dependencies.init)
    }

    static func build(
        dependencies: ProfileFeature.Dependencies,
        fromRoute route: Route?
    ) -> UIViewController {
        return ProfileViewController(dependencies: dependencies)
    }
}

With property wrappers, I can remove all the boilerplate:

private struct ProfileFeature: Feature {

    @Dependency var client: HTTPClientProtocol

    func build(fromRoute route: Route?) -> UIViewController {
        return ProfileViewController(client: client)
    }
}

The Feature became a struct to make use of the compiler's synthesized initializers, and the properties are automatically resolved by RouterService. You don't need to create the annoying dependenciesInitializer type anymore and you don't need to worry about features that have zero or one dependency.

This simplified structure makes it easier to develop and test new features. If you want to test build(), you can do either:

let feature = ProfileFeature()
feature.resolve(withStore: yourCustomStore)
feature.build(...)

or the more useful injection through the init:

let feature = ProfileFeature(client: .init(resolvedValue: myMockClient))
feature.build(...)

The original Dependency protocol was also removed because it was just an alias for AnyObject.

0.2.0 - Memory Management

10 Apr 17:59
Compare
Choose a tag to compare
  • Dependencies are now registered with a closure instead of a plain instance. RouterService now retains dependencies weakly, meaning that your instances will correctly deallocate if no features are using them, and allocate again if a feature requests it again in the future. Before this change, any dependency would be alive 100% of the time.
  • Updates to the Example project. There is now a more complete example.