1

I am creating a module comprised of several services. There is common functionality across these services. I wanted to adhere to DRY, so I created a "base" service and registered it in the module:

angular.module("ModuleA").service("BaseService", function () {...});

Then I can use that in my other services, like so:

angular.module("ModuleA").service("ChildService", function (BaseService) {...});

That works fine. However, I wanted the "base" service to be private/internal to this module. My app obviously depends on this module, and I don't want controllers etc. using the BaseService directly, which they can do since it is registered in ModuleA.

Is there a way to share the functionality in the BaseService class with several other services without exposing it to the entire application?

2
  • 1
    Have you considered the use of module namespacing and dependency injection to help you manage services? (i.e. angular.module("ModuleA.Services.Subservice", ["ModuleA.Services"]).service("ChildService", ["BaseService", function(BaseService) { ... }]);) Commented May 1, 2014 at 6:07
  • 1
    Just a thought... If your angular module is wrapped in a self-executing function, you can define globals within the self-executing function, which will be accessible from within the module but not from outside. Commented May 1, 2014 at 6:17

1 Answer 1

2

One option to achieve your goal is to use $provide.provider alongside with module.config. You should register your services via $provide.provider not $provide.service -- since $provide.service is just syntactic sugar over $provide.provider, there is no semantic difference. If anything unclear give me a shout.

DEMO and the essence of the approach:

var servicesModule = angular.module('services',[]);

servicesModule.provider("serviceA", function(){

  var _BaseConstructor = null;

  return {

    setBaseConstructor : function(BaseConstructor){
      _BaseConstructor = BaseConstructor;
    },

    $get : function(){

      function ServiceA(){
        this.callA = function(){
          return "calling A";
        }    
      }

      ServiceA.prototype = new _BaseConstructor();

      return new ServiceA();

    }

  }

});

servicesModule.config( function (serviceAProvider){

  // this will be totally inaccessible from outside
  function Base(){

    this.callBase = function(){
      return "calling base";
    }  

  }

  serviceAProvider.setBaseConstructor(Base);

});
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, I understand the approach. If I have multiple services that use the same base, I will add lines in the .config function for serviceBProvider.setBaseConstructor(Base) and serviceCProvider.setBaseConstructor(Base) etc. Do I have that right?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.