0

I'm trying to make a base in-repo addon that provides functionality through namespace like platform/services/whatever.

In addition to that I want if another addon isEnabled() that extends or reopens that same service (in some way) I want it to all be merged together without having to call the second addon's service by name like platform-second/services/whatever

I just want a nice clean abstraction. The reason I'm doing it this way is because based on an ENV variable, I need to build / inject different stuff into index.html and different app.imports.

and I want it to be completely separated into separate little in-repo addons to keep it clean.

I want the app to not need to know the platform but just be able to utilize methods of the general platform addon.

So for example platform.services.whatever.myMethod() might be a noOp by default, but if the second addon extends that and implements that, it'll fire that version instead automatically.

Wonder if I'm making any sense at all LOL

If you have any tips or advice on how one might implement this setup, please let me know.

I currently have the in-repo addons built but ideally I'd have the base platform addon be the one that actually has the app folder contents and the other addons that "extend" or "override" the methods / properties of that addon's objects would just be isEnabled() based on that ENV variable.

I should add that I can't simply do merge tree and override the original file because I need the base functionality of those files.

So if I extend one method of the base platform.services.whatever.myMethod() then I still need the rest of that services methods and properties as well.

Joshua F. Rountree
  • 1,462
  • 2
  • 14
  • 30

1 Answers1

0

So, it's hard for me to be too specific because your question was a bit vague as to the details, but no worries. I'll throw some ideas out and we can hopefully reach some useful conclusions together :)

If you need different objects at runtime, the trick is to register different versions of your service in the dependency injection container depending on configuration (as is common in DI based programming). So have your base service in your addon, and even some concrete implementations that extend the base with different implementations of certain methods. And then, in your app, you have an initializer that looks at the different ENV variables and determines which of the services to inject. You always inject under the same key service:some-service. So, baseClass = Ember.Object.extend() and impl1 = baseClass.extend({methodToOverride: ...} allows you to keep all of the baseClass methods except for the methods you override. So you have successfully avoided the caller having to know whether some parent or child is handling service.someMethod

Now if it's only at build time, then your in node.js land (require() and module.exports. With pojos or es6 you have a number of ways to achieve inheritance (prototype inheritance, $.extend for hierarchically merging pojos, es6 extends)...take your pick. But just from a programming design pattern perspective, it seems like your addon would need to expose a factory that abstracts out the creation of an object that conforms to some interface. So export some module that has a create method that takes in an options object and returns the correct impl.

mistahenry
  • 8,554
  • 3
  • 27
  • 38