square / Cleanse

Lightweight Swift Dependency Injection Framework
Other
1.79k stars 90 forks source link

Not sure how to proceed with Swift3 project #51

Closed mpp-davel closed 7 years ago

mpp-davel commented 7 years ago

Hi,

I'm trying to get something very simple working: a single component which installs a single module which provides an implementation for a single protocol.

Essentially, all I want to do is to provide an implementation of a protocol without having to manually inject (potentially many dependent objects) via constructors. Have I misunderstood that Cleanse can help with this?

I don't know how to go about a Swift 3 solution, as I'm finding it hard to find docs/examples featuring the new syntax for the swift-3 branch, but this is my attempt:

The root component and implementation

protocol MyRootProtocol
{
    func test()
}

struct MyRoot : MyRootProtocol
{
    let myService:MyServiceProtocol

    func test()
    {
        self.myService.echo(message: "hello world")
    }
}

struct SingletonScope : Cleanse.Scope {}

struct MyRootComponent : Cleanse.Component
{
    typealias Root = MyRootProtocol
    typealias Scope = SingletonScope

    //Install the modules we have made
    static func configure(binder: Binder<MyRootComponent.Scope>)
    {
        binder.include(module:MyServiceModule.self)
    }

    static func configureRoot(binder bind: ReceiptBinder<MyRootProtocol>) -> BindingReceipt<MyRootProtocol>
    {
        return bind.to(factory:
        {
            () -> MyRoot in
            return MyRoot()
        })
    }
}

The service module and implementation

protocol MyServiceProtocol
{
    func echo(message:String) -> Void
}

struct MyServiceImplementation : MyServiceProtocol
{
    func echo(message:String) -> Void
    {
        print("echo: \(message)")
    }
}

struct MyServiceModule : Cleanse.Module
{
    static func configure(binder: Binder<SingletonScope>)
    {
        binder
        .bind(MyServiceProtocol.self)
        .sharedInScope()
        .to
        {
            () -> MyServiceProtocol in
            return MyServiceImplementation()
        }
    }
}

Any help would be most appreciated! Cheers!

mpp-davel commented 7 years ago

After some trial and error, I got it working - hope this might help anyone looking for a Swift3 example:

The root component and implementation

struct MyRoot
{
    let myService:MyServiceProtocol

    func test()
    {
        self.myService.echo(message: "hello world")
    }
}

struct MyRootComponent : Cleanse.RootComponent
{
    typealias Root = MyRoot

    static func configure(binder: UnscopedBinder)
    {
       binder.include(module: MyServiceModule.self)
    }

    static func configureRoot(binder bind: ReceiptBinder<MyRoot>) -> BindingReceipt<MyRoot>
    {
        return bind.to(factory: MyRoot.init)
    }
}

The service module and implementation

protocol MyServiceProtocol
{
    func echo(message:String) -> Void
}

struct MyServiceImplementation : MyServiceProtocol
{
    func echo(message:String) -> Void
    {
        print("echo: \(message)")
    }
}

struct MyServiceModule : Cleanse.Module
{
    static func configure(binder: UnscopedBinder)
    {
        binder
        .bind(MyServiceProtocol.self)
        .to
        {
            () -> MyServiceProtocol in
            return MyServiceImplementation()
        }
    }
}

Building the component

let myRoot = try! ComponentFactory.of(MyRootComponent.self).build()