I think you would do this in Go like this:
package logger
type UserInfoProvider interface {
// functions that your logger needs
}
type ILogger interface { // please don't actually call it ILogger. Just Logger, or even just L, since your package is called logger
//functions that your logger has
}
type Logger struct {
userInfoProvider UserInfoProvider
// any other fields your logger needs
}
func NewLogger(userInfoProvider UserInfoProvider, /* other fields */) *Logger {
return &Logger{userInfoProvider, /* other fields */}
}
package main
import "logger"
import "useinfo"
func main() {
getUserInfo := userinfo.NewGetUserInfo()
l := logger.NewLogger(getUserInfo, /* other fields */)
}
Note that the logger package does not need to know anything about the userinfo package. The NewLogger function specifies the parameters it needs in order to do whatever it does. Because of the implicit implementations of interfaces, you just need to make sure that the value returned by userinfo.NewGetUserInfo() implements the methods defined in logger.UserInfoProvider.