I don’t know which subject could be better so first I show you the code:
// You can edit this code!
// Click here and start typing.
package main
import "fmt"
// The interface fulfilled by S
type I interface {
Method()
}
// Fulfills interface I
type S struct{}
// Method to fulfill I
func (s S) Method() {
fmt.Println("Method exists")
}
// Factory that returns the implementation of I
func Factory() func() S {
return func() S {
return S{}
}
}
// Factory that returns the interface I
type InterfaceFactory func() I
// Wants to have the "normal" factory
func IWantToGetAFactory(f func() S) {
f().Method()
}
// Wants to have the "interface" factory
func IWantToGetAnInterfaceFactory(f InterfaceFactory) {
f().Method()
}
func main() {
IWantToGetAFactory(Factory())
IWantToGetAnInterfaceFactory(Factory())
}
The problem is that IWantToGetAnInterfaceFactory accepts only InterfaceFactory. Now that I provide Factory it fails since Go seems not to recognize that
func() I
Is a subset of
func() S
Is there a way how I can achive this nevertheless?
That is not possible. In my real-world use-case the actual factory method returns a concrete object (Type A). This factory method is injected in another package where I do not want to use A but an Interface.
I know that I could do this But I have the interface in package A where I use the factory and the factory itself in package B while di takes place in package C. And A should not know anything about the implementation within package B.
But it seems to be not possible. Maybe sth. else comes up.
Thank you for this detailed instruction. This is a good idea indeed. But then c needs to know about a.I which I would like to avoid.
The intention behind this is to have internal interfaces specified where there are used at the end. They are just for the internal package usage. They are even not exported.
To make it more visible: We have a multi tenancy application which provides one database per tenant. I implemented a store which has methods like CreateUser, UpdateUser etc. There are many of these methods which are all implemented by a type Store in the package store.
In the http handler I only want to provide methods via interface that are needed. so there is an interface http.createUserStore (just an example) which contains only the method CreateUser. That interface is not exported.
For the multi tenancy I have a factory method which gives me a store (contains the database connection) by tenant. The implementation looks like: