{"action":"created","issue":{"url":"https://api.github.com/repos/simpleinjector/SimpleInjector/issues/364","repository_url":"https://api.github.com/repos/simpleinjector/SimpleInjector","labels_url":"https://api.github.com/repos/simpleinjector/SimpleInjector/issues/364/labels{/name}","comments_url":"https://api.github.com/repos/simpleinjector/SimpleInjector/issues/364/comments","events_url":"https://api.github.com/repos/simpleinjector/SimpleInjector/issues/364/events","html_url":"https://github.com/simpleinjector/SimpleInjector/issues/364","id":197826815,"number":364,"title":"Improve ambient context-less support in decorators","user":{"login":"dotnetjunkie","id":1506621,"avatar_url":"https://avatars.githubusercontent.com/u/1506621?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnetjunkie","html_url":"https://github.com/dotnetjunkie","followers_url":"https://api.github.com/users/dotnetjunkie/followers","following_url":"https://api.github.com/users/dotnetjunkie/following{/other_user}","gists_url":"https://api.github.com/users/dotnetjunkie/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnetjunkie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnetjunkie/subscriptions","organizations_url":"https://api.github.com/users/dotnetjunkie/orgs","repos_url":"https://api.github.com/users/dotnetjunkie/repos","events_url":"https://api.github.com/users/dotnetjunkie/events{/privacy}","received_events_url":"https://api.github.com/users/dotnetjunkie/received_events","type":"User","site_admin":false},"labels":[{"id":197522071,"url":"https://api.github.com/repos/simpleinjector/SimpleInjector/labels/enhancement","name":"enhancement","color":"84b6eb","default":true},{"id":197762005,"url":"https://api.github.com/repos/simpleinjector/SimpleInjector/labels/feature","name":"feature","color":"0052cc","default":false},{"id":197524790,"url":"https://api.github.com/repos/simpleinjector/SimpleInjector/labels/task","name":"task","color":"5319e7","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/simpleinjector/SimpleInjector/milestones/13","html_url":"https://github.com/simpleinjector/SimpleInjector/milestone/13","labels_url":"https://api.github.com/repos/simpleinjector/SimpleInjector/milestones/13/labels","id":1698384,"number":13,"title":"Backlog","description":"","creator":{"login":"dotnetjunkie","id":1506621,"avatar_url":"https://avatars.githubusercontent.com/u/1506621?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnetjunkie","html_url":"https://github.com/dotnetjunkie","followers_url":"https://api.github.com/users/dotnetjunkie/followers","following_url":"https://api.github.com/users/dotnetjunkie/following{/other_user}","gists_url":"https://api.github.com/users/dotnetjunkie/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnetjunkie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnetjunkie/subscriptions","organizations_url":"https://api.github.com/users/dotnetjunkie/orgs","repos_url":"https://api.github.com/users/dotnetjunkie/repos","events_url":"https://api.github.com/users/dotnetjunkie/events{/privacy}","received_events_url":"https://api.github.com/users/dotnetjunkie/received_events","type":"User","site_admin":false},"open_issues":12,"closed_issues":3,"state":"open","created_at":"2016-04-11T16:54:09Z","updated_at":"2016-12-29T09:19:54Z","due_on":null,"closed_at":null},"comments":2,"created_at":"2016-12-28T09:57:39Z","updated_at":"2016-12-29T09:57:45Z","closed_at":null,"body":"Since v3.2 (or specifically #226) Simple Injector has support for working with scopes that flow through the object graph instead of being held in a AsyncLocal or ThreadLocal storage.\r\n\r\nThis support however breaks down when working with decorators that use decoratee factories, as shown in the following example:\r\n\r\n``` c#\r\nsealed class CommandHandlerProxy<T> : ICommandHandler<T>\r\n{\r\n    private readonly Func<ICommandHandler<T>> commandHandlerFactory;\r\n\r\n    public void Handle(T cmd) {\r\n        ICommandHandler<T> handler = commandHandlerFactory();\r\n        handler.Handle(cmd);\r\n    }\r\n}\r\n```\r\n\r\nSince the `Func<ICommandHandler<T>>` will be generated by Simple Injector as a singleton, it becomes impossible for any previously defined Scope to flow through the object graph to the dependencies of this decotator (including the decoratee).\r\n\r\nThe typical solution would be to inject the `Scope` into the class and resolve from the `Scope`, but that obviously won't work when resolving the decoratee, because that would lead to a circular reference and would cause a stack overflow.\r\n\r\nThis could be solved by allowing the `Func<ICommandHandler<T>>` itself to get constructed using the `Scope` instance, which means that the `Func<T>` itself should be either transient or scoped itself, since a func injected into another decorator instance would need a different Scope. This however would complicate the design a lot, since currently the `Func<T>` is always a singleton. It would mean that the decorator sub system should start to analyze the remaining object graph to find out whether `Scope` is being injected anywhere, and if so, the `Func<T>` dependency should hold the `Scope` and become itself a `Scoped` registration at most.\r\n\r\nThis will be really complicated and could even be confusing to users. The only other solution I can think of that would possibly work is to allow the injection of an `Func<Scope, ICommandHandler<T>>` into decorators:\r\n\r\n``` c#\r\nsealed class ScopedCommandHandlerProxy<T> : ICommandHandler<T>\r\n{\r\n    private readonly Scope scope;\r\n    private readonly Func<Scope, ICommandHandler<T>> commandHandlerFactory;\r\n\r\n    public void Handle(T cmd) {\r\n        ICommandHandler<T> handler = commandHandlerFactory(scope);\r\n        handler.Handle(cmd);\r\n    }\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/simpleinjector/SimpleInjector/issues/comments/269606958","html_url":"https://github.com/simpleinjector/SimpleInjector/issues/364#issuecomment-269606958","issue_url":"https://api.github.com/repos/simpleinjector/SimpleInjector/issues/364","id":269606958,"user":{"login":"dotnetjunkie","id":1506621,"avatar_url":"https://avatars.githubusercontent.com/u/1506621?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnetjunkie","html_url":"https://github.com/dotnetjunkie","followers_url":"https://api.github.com/users/dotnetjunkie/followers","following_url":"https://api.github.com/users/dotnetjunkie/following{/other_user}","gists_url":"https://api.github.com/users/dotnetjunkie/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnetjunkie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnetjunkie/subscriptions","organizations_url":"https://api.github.com/users/dotnetjunkie/orgs","repos_url":"https://api.github.com/users/dotnetjunkie/repos","events_url":"https://api.github.com/users/dotnetjunkie/events{/privacy}","received_events_url":"https://api.github.com/users/dotnetjunkie/received_events","type":"User","site_admin":false},"created_at":"2016-12-29T09:57:45Z","updated_at":"2016-12-29T09:57:45Z","body":"> Another solution would be to let Simple Injector provide a CurrentScopeProvider, which is ofcourse a singleton. \r\n\r\nThis is impossible, because that would reintroduce an ambient context in the background, which is the thing this feature tries to 'solve'.\r\n\r\n> I like the idea of `Func<Scope, ICommandHandler<T>>`. It is however a very technical, probably very hard to document, solution.\r\n\r\nThat's true. This whole ambient context-less idea is very complex and this is exactly what Autofac users are struggling with on a day-to-day basis."}}
{"actor":{"display_login":"dotnetjunkie"}}