Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MVC: service injecting fails #1343

Closed
zheeeng opened this issue Aug 21, 2019 · 3 comments
Closed

MVC: service injecting fails #1343

zheeeng opened this issue Aug 21, 2019 · 3 comments

Comments

@zheeeng
Copy link

zheeeng commented Aug 21, 2019

package parse

import (
	"github.com/kataras/iris/mvc"
)

type Parser interface {
	Parse() string
}

type parser struct {
	inner string
}

func InitParser() Parser {
	return &parser{
		inner: "hello",
	}
}

func (p *parser) Parse() string {
	return p.inner
}

func App(app *mvc.Application) {
	parser := InitParser()

	app.Register(parser)

	app.Party("/parse").Configure(ParseApp)
}

func ParseApp(app *mvc.Application) {
	service := NewService()
	app.Register(service)

	app.Handle(new(controller))
}

type Service interface {
}

type service struct{}

func NewService() Service {
	return &service{}
}

type controller struct {
	Service Service
	Parser  Parser
}

func (c *controller) Get() string {
	return c.Parser.Parse()
}

This code will throw Internal Server Error:

Trace: runtime error: invalid memory address or nil pointer dereference

cos the c.Parser is nil

If we change the controller to

type controller struct {
	Parser  Parser
}

There is no problems.

@kataras
Copy link
Owner

kataras commented Aug 22, 2019

@zheeeng The problem here is that *parser is a Service too as Service does not contain any method and it's just an interface{} which binds to everything. So the *parser is bind to the Service field instead of the Parser.

@kataras
Copy link
Owner

kataras commented Aug 22, 2019

This is the same as you posted before: #1342.

These work:

type controller struct {
	Parser  Parser
}

type controller struct {
	Parser  Parser
        Service Service // (or interface {}, it's the same in your case)
}

And that's because it tries to match it by order of registering, because the Service field accepts anything, and you bind the *parser so it does bind to it and stops there, all binding values are registered so it does not continue to the Parser field (in Iris controllers, a binding value cannot be binded to more than one field of struct or input parameter of a function).

What we can do here?

Here we can add "priorities" so the Parser field binds to the *parser as it has methods and completes the interface. But in your previous issue where two fields are expecting any value and two binding values are registered, we can't do that, all fields have the same priority because they are empty interface{} , so the order of registering those binding values matters. These all are not real-world scenarios though.

@zheeeng zheeeng closed this as completed Aug 23, 2019
kataras added a commit that referenced this issue Aug 26, 2019
…nge the order of controller's fields and their registered valid dependencies relative to: #1343
@kataras
Copy link
Owner

kataras commented Aug 26, 2019

Hello @zheeeng,

With the recent commit we have added the ability to customize and change the order of fields and their valid available registered values (if more than one) through the mvc.Application.Sorter field. It defaults to nil but you can change it. We have a builtin sorter(SortByNumMethods) which does exactly what you want here.

func App(app *mvc.Application) {
        app.SortByNumMethods()

	parser := InitParser()
	app.Register(parser)
	app.Party("/parse").Configure(ParseApp)
}

@kataras kataras added this to the v12.0.0 milestone Oct 26, 2019
github-actions bot pushed a commit to goproxies/github.com-kataras-iris that referenced this issue Jul 27, 2020
…nge the order of controller's fields and their registered valid dependencies relative to: kataras#1343

Former-commit-id: 5bd9e02e5fafca135d17cad87f4a9aec526b333b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants