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] Can we use dependencies in middleware? #1198

Closed
zheeeng opened this issue Feb 18, 2019 · 5 comments

Comments

@zheeeng
Copy link

commented Feb 18, 2019

I want to add a session validation middleware for some specific routes, seems the middleware can only access the Context not other registered dependencies.

BTW: MVC route registered sessons.Sessions::Start as service. And I want to check a field 'authenticated' if fails middleware redirect client to another route.

  1. I have no idea how to use a service outside a controller.
  2. I tried registering service in controller's BeforeActivation hook, but failed.
type controller struct {
	Ctx     iris.Context
	Session *sessions.Session
}

func (c *controller) BeforeActivation(b mvc.BeforeActivation) {
	b.Router().Use(func (ctx iris.Context) {
	        fmt.Println(c.Session)    // it's nil
	        ctx.Next()
        })
}

func (c *controller) Get() interface{} {
	fmt.Println(c.Session)  // it's not nil
	return 200
}

@zheeeng zheeeng changed the title [MVC] Can we use dependencies in Middleware? [MVC] Can we use dependencies in middleware? Feb 18, 2019

@kataras

This comment has been minimized.

Copy link
Owner

commented Feb 19, 2019

Hello @zheeeng, if a dependency is dynamic, such as session (requires the http context) then it is only filled on the mvc handler itself, not the whole route cycle. Reccomended way would be to use the BeginRequest and EndRequest to control the serve flow inside a controller.

// [...]

func (c *controller) BeginRequest(ctx iris.Context) {
	fmt.Println(c.Session) // it's NOT nil.
	// Use ctx.StopExecution() to interrupt and not procceed with the 'Get' method.
}

func (c *controller) EndRequest(ctx iris.Context) {}

// [...]

Other way, could be to register middleware before the mvc registration, after all the b.Router() is just the Party that this controller was registered to but I assume that you already know that.

Examples of registering middleware inside a controller can be found at: https://github.com/kataras/iris/tree/master/_examples/mvc/middleware.

About your title question, yes you can but this is about handlers and not mvc indeed, read more at: https://github.com/kataras/iris/tree/master/_examples/hero/basic

@kataras

This comment has been minimized.

Copy link
Owner

commented Feb 19, 2019

However, if all those information above does not satisfy you. I am open to introduce a way in the upcoming v11.2 to wrap the existing b.Router to something else or create a new method that would be able to register middleware with all controller's dependencies inside (this will have performance cost though, because it will have to execute the binder on every handler at any way)

@kataras kataras added the question label Feb 19, 2019

@zheeeng

This comment has been minimized.

Copy link
Author

commented Feb 19, 2019

BeginRequest and EndRequest works. I switched to use it as the controller interceptor.

I expected to have the fully featured AOP(aspect-oriented programming) MVC dev experience.

Above controller level, inject pre-handler and post-handler for all controller methods. in controller level, inject pre-handler and post-handler for some specific methods. And I expected the injected dependencies are accessible in these pre/post-handlers.

@kataras

This comment has been minimized.

Copy link
Owner

commented Jul 23, 2019

Injection works inside controller's methods and inside any other regular handler and middleware through hero, to understand your request, you want controller's router to be able to accept the mvc application's dependencies? You can already do that by:

hero.Register(..dependencies)
func (c *Controller) BeforeActivation(b iris.BeforeActivation) {
    b.Router.Use(hero.Handler(mymiddleware))
}

^ if that's the case we can "automative" it but I need to understand exactly the request before start coding it @zheeeng

If you mean that you want to inject those deps at BeginRequest and EndRequest functions input arguments, that's not possible and not recommended at all. The controller's fields-dependencies are available, use them instead.

@kataras

This comment has been minimized.

Copy link
Owner

commented Jul 24, 2019

More info at : #1031

@kataras kataras closed this Aug 14, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.