{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/orleans/issues/965","labels_url":"https://api.github.com/repos/dotnet/orleans/issues/965/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/orleans/issues/965/comments","events_url":"https://api.github.com/repos/dotnet/orleans/issues/965/events","html_url":"https://github.com/dotnet/orleans/pull/965","id":114157174,"number":965,"title":"Feature: Per-Grain-class Request Interceptors","user":{"login":"ReubenBond","id":203839,"avatar_url":"https://avatars.githubusercontent.com/u/203839?v=3","gravatar_id":"","url":"https://api.github.com/users/ReubenBond","html_url":"https://github.com/ReubenBond","followers_url":"https://api.github.com/users/ReubenBond/followers","following_url":"https://api.github.com/users/ReubenBond/following{/other_user}","gists_url":"https://api.github.com/users/ReubenBond/gists{/gist_id}","starred_url":"https://api.github.com/users/ReubenBond/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ReubenBond/subscriptions","organizations_url":"https://api.github.com/users/ReubenBond/orgs","repos_url":"https://api.github.com/users/ReubenBond/repos","events_url":"https://api.github.com/users/ReubenBond/events{/privacy}","received_events_url":"https://api.github.com/users/ReubenBond/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/dotnet/orleans/labels/cla-already-signed","name":"cla-already-signed","color":"009800"},{"url":"https://api.github.com/repos/dotnet/orleans/labels/enhancement","name":"enhancement","color":"84b6eb"},{"url":"https://api.github.com/repos/dotnet/orleans/labels/work-in-progress","name":"work-in-progress","color":"fad8c7"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":23,"created_at":"2015-10-29T22:03:07Z","updated_at":"2015-11-01T04:32:50Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/dotnet/orleans/pulls/965","html_url":"https://github.com/dotnet/orleans/pull/965","diff_url":"https://github.com/dotnet/orleans/pull/965.diff","patch_url":"https://github.com/dotnet/orleans/pull/965.patch"},"body":"This feature allows users to override `Grain.Invoke(InvokeMethodRequest request, IGrainMethodInvoker invoker)` in order to perform request interception on a per-Grain-class level.\r\n\r\nAs requested by @yevhen in #749.\r\n\r\nExample:\r\n```C#\r\npublic class InterceptRequestGrain : Grain, ISomeGrain \r\n{\r\n  protected override Task<object> Invoke(InvokeMethodRequest request, IGrainMethodInvoker invoker)\r\n  {\r\n    RequestContext.Set(\"InterceptedValue\", 74);\r\n    return base.Invoke(request, invoker);\r\n  }\r\n\r\n  // Other methods...\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/dotnet/orleans/issues/comments/152793044","html_url":"https://github.com/dotnet/orleans/pull/965#issuecomment-152793044","issue_url":"https://api.github.com/repos/dotnet/orleans/issues/965","id":152793044,"user":{"login":"gabikliot","id":10171207,"avatar_url":"https://avatars.githubusercontent.com/u/10171207?v=3","gravatar_id":"","url":"https://api.github.com/users/gabikliot","html_url":"https://github.com/gabikliot","followers_url":"https://api.github.com/users/gabikliot/followers","following_url":"https://api.github.com/users/gabikliot/following{/other_user}","gists_url":"https://api.github.com/users/gabikliot/gists{/gist_id}","starred_url":"https://api.github.com/users/gabikliot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gabikliot/subscriptions","organizations_url":"https://api.github.com/users/gabikliot/orgs","repos_url":"https://api.github.com/users/gabikliot/repos","events_url":"https://api.github.com/users/gabikliot/events{/privacy}","received_events_url":"https://api.github.com/users/gabikliot/received_events","type":"User","site_admin":false},"created_at":"2015-11-01T04:32:50Z","updated_at":"2015-11-01T04:32:50Z","body":"And thanks @veikkoeeva for sharing the links:\r\n[NancyFx: The before and after module hooks](https://github.com/NancyFx/Nancy/wiki/The-before-and-after-module-hooks) - they have pre and post decorators (which they called interceptors, like I initially did), not full interceptors.\r\n\r\nAnd in [Logging and Intercepting Database Operations](https://msdn.microsoft.com/en-us/data/dn469464.aspx) there is yet a third option: pre and post interceptors with optional returned result. If the pre interceptor returns a result, the actual operation is not invoked and the interceptor result is returned instead. But still, the pre interceptor does not invoke the original operation itself."}}