hmlongco / Factory

A new approach to Container-Based Dependency Injection for Swift and SwiftUI.
MIT License
1.93k stars 116 forks source link

Registering a protocol with an associatedtype #216

Closed fraserscottmorrison closed 3 months ago

fraserscottmorrison commented 4 months ago

Hiya, Ive been trying to register a protocol that has an associatedtype as a dependency, but I have compilation error. My project has various packages and Im using your modular development design. The following is a simplified example

In PackageB:

public protocol ModuleProtocol {
    associatedtype D: Codable
    func show(details: D) -> any View
}

Registering the dependency with the protocol. The compiler instructs me to use any due to associatedtype

extension Container {
    public var module: Factory<(any ModuleProtocol)?> { promised() }
}

In PackageA, which has PackageB as a dependency: The class that adheres to ModuleProtocol

public final class Module: ModuleProtocol {
    public typealias D = Details

    public func show(details: Details) -> any View {
        DetailsView(details: details)
    }
}
struct Details: Codable {}

Auto register the module class

extension Container: AutoRegistering {
    public func autoRegister() {
        module.register { Module() }
    }
}

Lastly, here I want to instantiate the dependency

if let module = Container.shared.module() {
    module.show(account: account) // compilation error here
}

I have a compilation error when trying to call the function of the instance Member 'show' cannot be used on value of type 'any ModuleProtocol'; consider using a generic constraint instead

Perhaps my knowlegde of swift generics is letting me down here. Do you know how I can avoid this error?

hmlongco commented 4 months ago

Can't do that with associated types, generics won't allow it.

fraserscottmorrison commented 4 months ago

Is it possible to register a protocol with associated types with Factory in another way?