ReactiveSwiftのActionで発火したSingalProducerをDisposeする方法の検討

# 問題

下記のようなActionがあるとします。

```swift
class ViewController: UIViewController {
    private let action = Action<Void, Void, Never> {
        SignalProducer { observer, lifetime in
            let workItem = DispatchWorkItem {
                observer.send(value: ())
                observer.sendCompleted()
            }
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: workItem)
            
            lifetime.observeEnded {
                workItem.cancel()
            }
        }
    }
}
```

下記各パターンで`viewDidAppear`で発火して、完了する前に`ViewController`が`deinit`しても、`dispose`されません。
[Action.swift#L143](https://github.com/ReactiveCocoa/ReactiveSwift/blob/6af9fec3e7877ebec9def9fa0fd0e34234ca8e93/Sources/Action.swift#L143)のソースからも`dispose`を管理していないため、`dispose`されないことがわかります。

```swift
    private let disposable = CompositeDisposable()

    override func viewDidLoad() {
        super.viewDidLoad()
        // パターン1
        self.action <~ self.reactive.viewDidAppear

        // パターン2
        self.action <~ self.reactive.viewDidAppear.take(during: self.reactive.lifetime)

        // パターン3
        self.disposable += self.action <~ self.reactive.viewDidAppear
    }

    // パターン4
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.action.apply().start()
    }

    deinit {
        self.disposable.dispose()
    }
```

# `dispose`する方法
`Action`内で生成した`SignalProducer`を直接`dispose`するしかなさそう


## パターン1
`<~`のバインディング演算子が使えず、また入力が必要な場合もスマートに値を入力できなさそうです。

```swift
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.action.apply().take(during: self.reactive.lifetime).start()
    }
```

## パターン2
`<~`のバインディング演算子が使えて、ソースから値を入力できるので、パターン1よりスマートそう。
ただ、余分に拡張関数を追加する必要があるので、コード量が必要。

```swift
    override func viewDidLoad() {
        super.viewDidLoad()
        self.reactive.action <~ self.reactive.viewDidAppear
    }

private extension Reactive where Base: ViewController {
    var action: BindingTarget<Void> {
        self.makeBindingTarget { base, _ in
            base.action.apply().take(during: base.reactive.lifetime).start()
        }
    }
}
```

## パターン3
入力に合わせて、`Lifetime`も送ってみる。
`Lifetime`しか対応できないため、他の`dispose`パターンに対応しきれない。

```swift
class ViewController: UIViewController {
    private let action = Action<(Void, Lifetime), Void, Never> {
        SignalProducer { observer, lifetime in
            let workItem = DispatchWorkItem {
                observer.send(value: ())
                observer.sendCompleted()
            }
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: workItem)
            
            lifetime.observeEnded {
                workItem.cancel()
            }
        }
        .take(during: $0.1)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.action <~ self.reactive.viewDidAppear.map(value: ((), self.reactive.lifetime))
    }
}
```

## パターン4
`SignalProducer`を`Action`の入力値にしてみる。

```swift
class ViewController: UIViewController {
    private let action = Action<SignalProducer<Void, Never>, Void, Never> {
        $0
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.action <~ self.reactive.viewDidAppear.compactMap { [weak self] in
            guard let self = self else { return nil }
            return SignalProducer { observer, lifetime in
                let workItem = DispatchWorkItem {
                    observer.send(value: ())
                    observer.sendCompleted()
                }
                
                DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: workItem)
                
                lifetime.observeEnded {
                    workItem.cancel()
                }
            }
            .take(during: self.reactive.lifetime)
        }
    }
}
```