3

I struggle to find a statisfying solution on how to expose service instances whose methods need to be accessed through multiple parts of my applications.

The situation

First things first, by a 'service', I mean an instance of a function that holds properties & methods which are exposed through an API.

Consider a REST service whose purpose it is to provide convenient methods to access REST points on a server. I would make the following assumptions on that service:

  • It must be available throughout the application. It is likely that as the app grows, there will be new components that need access.

  • There is no need of multiple instances of this service. We can consider it a singleton.

My solutions

I can think of 2 possible solutions:

Concatenating scripts & utilizing the global object

I could combine all my script files (e.g rest.service.js, app.js) into a single file and create an object property on the global object (like App). Then, I could attach service instances to this object. This allows me to do something like this from everywhere within the app:

App.restService.get()

However, even if I wrap each service in an IIFE, i still have to add some variables on window in order to retrieve instances.

Using commonJS / AMD modules

I could require() my service instances from everywhere by using require.js / browserify

The issues

Now I got a headache because on the one hand, people are telling me that polluting the global object is bad practice. Singletons are bad practice also.

On the other hand, we make a lot of effort to 'uglify' scripts, each byte saved considered an enhancement. Using browserify would lead to the same script injected in multiple files, though (I'm using web-components, therefore I've got a lot of isolated scripts). Not mentioning the fact that I have no idea on how to provide a state-safe service using browserify.


So how should I approach this problem?

How should I expose standard services that may or may not be instantiated multiple times? How should I implement state-safe ones?

Community
  • 1
  • 1
Wottensprels
  • 3,166
  • 2
  • 26
  • 38

2 Answers2

1

Just a starting point (but too long to be a comment) I really enjoy the strategy used by AngularJs, where you always instantiate services within a container - and every time you instantiate something you also specify which modules should be injected into it:

angular.module('myApp.services', []); // the second argument are the dependencies (an empty array

At any point, you can retrieve your modules and add functionalities:

var services = angular.module('myApp.services');
services.factory('yourServiceName', //
     ['other', 'service', 'dependencies'],
     function(other, service, dependencies){
         other.doStuff();
         service.doStuff();
         dependencies.doStuff();
         [..]
     });

You can then inject your module in other modules

var myApp = angular.module('na', ['yourServiceName'])

In angular, the app is instantiated by the framework itself - but I guess you can develop a entry point for your app, so that you can use your services.

..unfortunately, I do not know exactly how this pattern is implemented - probably all the modules are stored within an instance of the application, so the global namespace is not polluted.

  • Thanks for your suggest. I enjoyed working with the concept of services in Angular, too. I always disliked DI, though, it felt weird to me, like I was abusing function arguments. – Wottensprels Nov 11 '14 at 14:22
1

This problem also confuses me a lot, I think there are two points I can figure out: 1) There must be an entry point for each service in global, otherwise it is impossible to get the one you need everywhere. It's not good to add many things in global, but I think service reference is the one deserved. 2) Config the service object other than initialization, for example, they can be only one ajax service object with different configuration to do different things. There are objects, so they can be merged and extended.

This is an interesting topic, I would like to see more opinions about, not just management of services, also other resources like templates, objects, files, etc.

sayume
  • 118
  • 1
  • 8