Ok.. I have, or am writing a web framework package, called mao.
I'd like to have my Route defined in the controller.
in mao
type (
Controller struct {
Route Route
}
Route struct {
Name, Host, Path, Method string
}
)
in mao importing package
controller/default.go
type DefaultController struct {
mao.Controller
}
func (this *DefaultController) Index() Response {
this.Route = mao.Route{"default_index","localhost","/", "GET"}
}
Now since I'd like to define my route inside the controller, the router, when instanced should read all controllers. That's the problem.
How do I pass the package name to my router so it's able to get all structs and functions in that package? Is it even possible?
I think you should have one struct for router (which may well be global, like http.DefaultClient) and then in constructor functions for your controllers you'd be able to inject this router as a dependency so that a relevant route is injected for the router. DI+interfaces make your code nice and testable, not only in Go.
Just an idea.
Honestly, I think you are doing it the wrong way. "auto registering" is obfuscating what happens and will lead to code that is hard to test and to reason about.
I would suggest to make controller an interface that should be satisfied by the concrete controllers and have a method
Add(c Controller)
on the router to assign the controller in the calling main project (that imports the router and the controllers). This should make your code understandable and explicit and is more in the spirit of go.The
database/sql
driver registration is more of a hack and should not be considered best practice.What you ask isn't possible in Go, since it doesn't have a way to enumerate all types in a package/program.
One alternative would be to follow the lead of the
database/sql
package, and have a system where other packages can register with it when imported.For example, to use the PostgreSQL driver with that package, you might do:
The postgres driver is registered during initialisation of the
github.com/lib/pq
package. Here is the relevant code from that package (eliding some parts that aren't relevant):Perhaps you could create a registration API like this to find the various implementations available in the program?