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

Access services in a decorator #67

Open
robations opened this issue Oct 17, 2016 · 7 comments
Open

Access services in a decorator #67

robations opened this issue Oct 17, 2016 · 7 comments
Milestone

Comments

@robations
Copy link

I've not thought this through fully, but is there a good reason not to allow access to dependencies in a decorator? I've had a few situations where I want to alter/augment some behaviour in a given service, but from the decorator I'm very limited in what I have access to.

Something like

bottle.decorator(
    "glass",
    function (original, beer) {
        return function () {
            original.fill(beer.pour());
            return original;
        }
    },
    "Beer"
);
@young-steveo
Copy link
Owner

If I follow you correctly, you want to be able to inject additional services into a decorator; basically the decorator would have it's own dependencies. Is that correct?

@robations
Copy link
Author

That is correct!

@young-steveo
Copy link
Owner

This makes sense to me; sounds like a good addition. Probably should add the feature to middleware as well. Possibly also add injection to factories, but not sure.

@robations
Copy link
Author

In case it helps, the use case is an npm module where I export a bottle container. Other modules can then consume these services but in some cases may either override or augment existing functionality.

It's a flexible architecture but, at the moment, decorating an existing service is constrained to services you can access using require() (or otherwise outside the realms of bottle).

@young-steveo young-steveo added this to the v2.0.0 milestone Nov 4, 2016
@mwillbanks
Copy link

@young-steveo yes, injection into factories, decorators and middleware is very nice...

For decorators think of something more or less that might want to hook an event on something else...

bottle.service('MyClassEmitsEvent', MyClassEmitsEvent);
bottle.service('MyEventWatcher', MyEventWatcher);

// assuming injectables would be an object of the injected parameters... otherwise container would be file also
bottle.decorator('MyClassEmitsEvent', 'MyEventWatcher', (service, injectables) => {
  service.on('event', injectables.MyEventWatcher.notify);
});

@young-steveo
Copy link
Owner

@mwillbanks Yeah, I'm going to get started on the new Bottle version soon; I'll include this feature. I hadn't considered putting the injectables before the final function, but I like the idea, thanks!

@ghost
Copy link

ghost commented Feb 27, 2020

Just as an FYI to any poor soul needing this solution, I've implemented the following which works well. It isn't pretty but beauty is skin deep.

function getDecorator(decoratorDependency,) {
  function decorate(someService) {
    // have much fun with decoratorDependency
    return someService;
  }
  return decorate;
}

module.exports = (container) => {
  container.decorator('someService', getDecorator(container.container.decoratorDependency);
};

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

3 participants