diff --git a/Documentation/Annotation.md b/Documentation/Annotation.md index fb56b91..815f1fe 100644 --- a/Documentation/Annotation.md +++ b/Documentation/Annotation.md @@ -8,7 +8,7 @@ This is commonly done on Android using Dagger 2, and we can now do something sim Resolver now supports resolving properties using the new property wrapper syntax in Swift 5.1. -``` +```swift class BasicInjectedViewController: UIViewController { @Injected var service: XYZService } @@ -24,7 +24,7 @@ The Injected property wrapper will automatically instantiate objects using the c ### Lazy Injection Resolver also has a LazyInjected property wrapper. Unlike using Injected, lazily injected services are not resolved until the code attempts to access the wrapped service. -``` +```swift class NamedInjectedViewController: UIViewController { @LazyInjected var service: XYZNameService func load() { @@ -37,7 +37,7 @@ Note that LazyInjected is a mutating property wrapper. As such it can only be us ### Weak Lazy Injection Resolver also has a WeakLazyInjected property wrapper. Like LazyInjected, services are not resolved until the code attempts to access the wrapped service. -``` +```swift class NamedInjectedViewController: UIViewController { @WeakLazyInjected var service: XYZNameService func load() { @@ -51,13 +51,13 @@ Note that LazyInjected is a mutating property wrapper. As such it can only be us You can use named service resolution using the `name` property wrapper initializer as shown below. -``` +```swift class NamedInjectedViewController: UIViewController { @Injected(name: "fred") var service: XYZNameService } ``` You can also update the name in code and 'on the fly' using @LazyInjected. -``` +```swift class NamedInjectedViewController: UIViewController { @LazyInjected var service: XYZNameService var which: Bool @@ -72,7 +72,7 @@ If you go this route just make sure you specify the name *before* accessing the ### Optional injection An annotation is available that supports optional resolving. If the service is not registered, then the value will be nil, otherwise it will be not nil: -``` +```swift class InjectedViewController: UIViewController { @OptionalInjected var service: XYZService? func load() { @@ -84,7 +84,7 @@ class InjectedViewController: UIViewController { ### Injection With Protocols Injecting a protocol works with all of the injection property wrappers. -``` +```swift protocol Loader { func load() } @@ -102,19 +102,19 @@ Registration of the class providing the protocol instance is performed exactly t You can specify and resolve custom containers using Injected. Just define your custom container... -``` +```swift extension Resolver { static var custom = Resolver() } ``` And specify it as part of the Injected property wrapper initializer. -``` +```swift class ContainerInjectedViewController: UIViewController { @Injected(container: .custom) var service: XYZNameService } ``` As with named injection, with LazyInjected you can also dynamically specifiy the desired container. -``` +```swift class NamedInjectedViewController: UIViewController { @LazyInjected var service: XYZNameService var which: Bool diff --git a/Documentation/Arguments.md b/Documentation/Arguments.md index 09aa80a..1823d2d 100644 --- a/Documentation/Arguments.md +++ b/Documentation/Arguments.md @@ -116,7 +116,7 @@ Why? Because property wrappers are at heart properties and they're immediately i It can't, for example, do `@Injected(args: self.editMode) var viewModel: XYZViewModel` as `self` isn't available. Swift won't allow it. That said, it's possible to be sneaky about it and pass arguments using `@LazyInjected`. -``` +```swift class NamedInjectedViewController: UIViewController { @LazyInjected var service: XYZNameService var editMode: Bool @@ -160,7 +160,7 @@ To put that into English, it means the dependency-injection system creates and c Data is never injected. If an object requires data or values created or manipulated during runtime I'd do something like the following.... -``` +```swift class DummyViewModel { func load(id: Int, editing: Bool) { } } diff --git a/Documentation/Containers.md b/Documentation/Containers.md index 69bbf16..a862102 100644 --- a/Documentation/Containers.md +++ b/Documentation/Containers.md @@ -10,7 +10,7 @@ In Resolver, a resolver instance contains its registration code, its resolution Inspect Resolver's code and you'll see the following. -``` +```swift public final class Resolver { public static let main: Resolver = Resolver() public static var root: Resolver = main @@ -23,7 +23,7 @@ Resolver creates a *main* container that it uses as its default container for al This basically means that when you do.... -``` +```swift extension Resolver: ResolverRegistering { static func registerAllServices() { register { XYZNetworkService(session: resolve()) } @@ -34,7 +34,7 @@ extension Resolver: ResolverRegistering { You're effectively doing... -``` +```swift extension Resolver: ResolverRegistering { static func registerAllServices() { main.register { XYZNetworkService(session: root.resolve()) } @@ -45,7 +45,7 @@ extension Resolver: ResolverRegistering { The static (class) register and resolve functions simply pass the buck to main and root, respectively. -``` +```swift public static func register(_ type: Service.Type = Service.self, name: Resolver.Name? = nil, factory: @escaping ResolverFactoryArgumentsN) -> ResolverOptions { return main.register(type, name: name, factory: factory) @@ -60,7 +60,7 @@ public static func resolve(_ type: Service.Type = Service.self, name: S Creating your own container is simple, and similar to creating your own scope caches. -``` +```swift extension Resolver { static let mock = Resolver() } @@ -68,7 +68,7 @@ extension Resolver { It could then be used as follows. -``` +```swift extension Resolver: ResolverRegistering { static func registerAllServices() { mock.register { XYZNetworkService(session: mock.resolve()) } @@ -91,7 +91,7 @@ This implies that if root were to point to a different container, like our *mock Now consider the following: -``` +```swift extension Resolver { static let mock = Resolver(parent: main) @@ -117,7 +117,7 @@ If a service is **not** found in *mock*, the *main* parent container will be se One might ask why we simply don't do the following: -``` +```swift extension Resolver { static func registerAllServices() { register { XYZNetworkService(session: resolve()) } @@ -138,7 +138,7 @@ But what if, for example, we want to keep both registrations and use the proper Consider the following: -``` +```swift extension Resolver { #if DEBUG static let mock = Resolver(parent: main) @@ -157,7 +157,7 @@ extension Resolver { And then somewhere in our code we do this before we enter a given section: -``` +```swift #if DEBUG Resolver.root = Resolver.mock #end @@ -165,7 +165,7 @@ Resolver.root = Resolver.mock And then when exiting that section: -``` +```swift #if DEBUG Resolver.root = Resolver.main #end diff --git a/Documentation/Injection.md b/Documentation/Injection.md index b3b23e5..57aea76 100644 --- a/Documentation/Injection.md +++ b/Documentation/Injection.md @@ -23,7 +23,7 @@ The first injection technique is to define a interface for the injection, and in #### The Class -``` +```swift class XYZViewModel { lazy var fetcher: XYZFetching = getFetcher() @@ -38,7 +38,7 @@ class XYZViewModel { #### The Dependency Injection Code -``` +```swift extension XYZViewModel: Resolving { func getFetcher() -> XYZFetching { return resolver.resolve() } func getService() -> XYZService { return resolver.resolve() } @@ -70,7 +70,7 @@ Property Injection exposes its dependencies as properties, and it's up to the De #### The Class -``` +```swift class XYZViewModel { var fetcher: XYZFetching! @@ -85,7 +85,7 @@ class XYZViewModel { #### The Dependency Injection Code -``` +```swift func setupMyRegistrations { register { XYZViewModel() } .resolveProperties { (resolver, model) in @@ -120,7 +120,7 @@ A Constructor is the Java term for a Swift Initializer, but the idea is the same #### The Class -``` +```swift class XYZViewModel { private var fetcher: XYZFetching @@ -141,7 +141,7 @@ class XYZViewModel { #### The Dependency Injection Code -``` +```swift func setupMyRegistrations { register { XYZViewModel(fetcher: resolve(), service: resolve()) } register { XYZFetcher() as XYZFetching } @@ -170,7 +170,7 @@ Method Injection is pretty much what it says, injecting the object needed into a #### The Class -``` +```swift class XYZViewModel { func load(fetcher: XYZFetching, service: XYZFetching) -> Data { @@ -207,7 +207,7 @@ Technically, Service Locator is its own Design Pattern, distinct from Dependency #### The Class -``` +```swift class XYZViewModel { var fetcher: XYZFetching = Resolver.resolve() @@ -222,7 +222,7 @@ class XYZViewModel { #### The Dependency Injection Code -``` +```swift func setupMyRegistrations { register { XYZFetcher() as XYZFetching } register { XYZService() } @@ -246,7 +246,7 @@ Annotation uses comments or other metadata to indication that dependency injecti #### The Class -``` +```swift class XYZViewModel { @Injected var fetcher: XYZFetching @@ -261,7 +261,7 @@ class XYZViewModel { #### The Dependency Injection Code -``` +```swift func setupMyRegistrations { register { XYZFetcher() as XYZFetching } register { XYZService() } diff --git a/Documentation/Installation.md b/Documentation/Installation.md index 36327d9..e7887fc 100644 --- a/Documentation/Installation.md +++ b/Documentation/Installation.md @@ -4,7 +4,7 @@ Resolver is available through Swift Package Manager. To install it simply include it in your package dependencies: -``` +```swift dependencies: [ .package(url: "https://github.com/hmlongco/Resolver.git", from: "1.1.2"), ] @@ -16,7 +16,7 @@ Or in Xcode via File > Swift Packages > Add Package Dependency... Resolver is available through CocoaPods. To install it, simply add the following line to your Podfile: -``` +```swift pod "Resolver" ``` diff --git a/Documentation/Names.md b/Documentation/Names.md index 0cf0817..73e1a63 100644 --- a/Documentation/Names.md +++ b/Documentation/Names.md @@ -121,7 +121,7 @@ Now the view controller gets the proper view model for the job. The `lazy var` e If you're using Resolver's property wrappers for injection, you can also do the same with `@LazyInjected`. -``` +```swift class NamedInjectedViewController: UIViewController { var editMode: Bool // set, perhaps, by calling segue @LazyInjected var viewModel: XYZViewModelProtocol diff --git a/Documentation/Optionals.md b/Documentation/Optionals.md index aeff412..30650fc 100644 --- a/Documentation/Optionals.md +++ b/Documentation/Optionals.md @@ -58,7 +58,7 @@ var abc: ABCServicing? = Resolver.resolve(ABCService.self) ## Optional annotation An annotation is available that supports optional resolving. If the service is not registered, then the value will be nil, otherwise it will be not nil: -``` +```swift class InjectedViewController: UIViewController { @OptionalInjected var service: XYZService? func load() { diff --git a/Documentation/Registration.md b/Documentation/Registration.md index 221450a..c8d99f9 100644 --- a/Documentation/Registration.md +++ b/Documentation/Registration.md @@ -27,7 +27,7 @@ Let's start by adding the master injection file for the entire application. Add a file named `AppDelegate+Injection.swift` to your project and add the following code: -``` +```swift import Resolver extension Resolver: ResolverRegistering { @@ -53,7 +53,7 @@ Let's say you have a group in your project folder named "NetworkServices", and y Go to the NetworkServices folder and add a swift file named: `NetworkServices+Injection.swift`, then add the following to that file... -``` +```swift #import Resolver extension Resolver { @@ -67,7 +67,7 @@ extension Resolver { Now, go back to your `AppDelegate+Injection.swift` file and add a reference to `registerMyNetworkServices`. -``` +```swift extension Resolver: ResolverRegistering { public static func registerAllServices() { registerMyNetworkServices() @@ -83,7 +83,7 @@ Now, housekeeping completed, return to `NetworkServices+Injection.swift` and ad Just as an example: -``` +```swift import Resolver extension Resolver { diff --git a/Documentation/Scopes.md b/Documentation/Scopes.md index 7e86409..a115c88 100644 --- a/Documentation/Scopes.md +++ b/Documentation/Scopes.md @@ -97,7 +97,7 @@ If you don't want this behavior, and if every request should get its own `unique This scope stores a *weak* reference to the resolved instance. -``` +```swift register { MyViewModel() } .scope(.shared) ``` diff --git a/Documentation/Storyboards.md b/Documentation/Storyboards.md index ea38293..e57a2b1 100644 --- a/Documentation/Storyboards.md +++ b/Documentation/Storyboards.md @@ -2,7 +2,7 @@ NOTE: As of Swift 5.1, we can now perform annotation using Property Wrappers. (See [Annotation](https://github.com/hmlongco/Resolver/blob/master/Documentation/Annotation.md).) -``` +```swift class MyViewController: UIViewController { @Injected var viewModel: XYZViewModel } @@ -15,7 +15,7 @@ Resolver supports automatic UIViewController property injection using the Storyb Let's assume the following view controller, which needs a XYZViewModel in order to function. -``` +```swift class MyViewController: UIViewController { var viewModel: XYZViewModel! } @@ -24,7 +24,7 @@ class MyViewController: UIViewController { Add the following to your section's [xxxxx+Injection.swift file](Registration.md#files): -``` +```swift extension MyViewController: StoryboardResolving { func resolveViewController(_ resolver: Resolver) { self.viewModel = resolver.optional() @@ -50,7 +50,7 @@ From its perspective, all of its properties just magically appear, ready and wai Add the following to your section's [xxxxx+Injection.swift file](Registration.md#files): -``` +```swift extension MyViewController: Resolving { func makeViewModel() -> XYZViewModel { return resolver.resolve() } } @@ -58,7 +58,7 @@ extension MyViewController: Resolving { And now the code contained in `MyViewController` becomes: -``` +```swift class MyViewController: UIViewController { lazy var viewModel = makeViewModel() } @@ -74,7 +74,7 @@ Some Dependency Injection systems like [SwinjectStoryboard](https://github.com/S Here's the equivalent Step 1 code in SwinjectStoryboard. -``` +```swift extension SwinjectStoryboard { class func setupMyStoryboard() { defaultContainer.storyboardInitCompleted(MyViewController.self) { (r, vc: MyViewController) in diff --git a/Documentation/Types.md b/Documentation/Types.md index 3e85cdb..8828316 100644 --- a/Documentation/Types.md +++ b/Documentation/Types.md @@ -38,7 +38,7 @@ Here the variable type is ABCService, so Resolver will lookup the registration f You can also explicitly tell Resolver the type of object or protocol you want to register or resolve. -``` +```swift Resolver.register(ABCServicing.self) { ABCService() } var abc = Resolver.resolve(ABCServicing.self) ```