Skip to content

NgModule FAQ enhancement request #21472

Closed

Description

@bibhas2

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

The NgModule FAQ, for the section Why is a service provided in a feature module visible everywhere? states:

This is by design. Extensibility through NgModule imports is a primary goal of the NgModule system. Merging NgModule providers into the application injector makes it easy for a module library to enrich the entire application with new services. By adding the HttpModule once, every application component can make HTTP requests.

But this fails to answer the question. The real question is: why can we not control the exportability of a service through the exports: [] list of a module? Why are all services exported from a module without giving the developers any control over it? In other words, why did the designers see services differently from the declarables in this regard?

Expected behavior

Explain the rationale behind why all services are exported by default where as the declarables must be added to the exports list. This aspect is not clear from the FAQ.

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Angular version: X.Y.Z


Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: XX  
- Platform:  

Others:

Activity

  1. alexeagle commented on Jan 11, 2018

    @alexeagle
    Contributor

    @kapunahelewong maybe this is already fixed?

  2. kapunahelewong commented on Jan 11, 2018

    @kapunahelewong
    Contributor

    HI @bibhas2 thank you for your questions. I'm working on the FAQs right now, so this is helpful. In the meantime, you might be interested in some of the new documentation we merged yesterday about NgModules. Does this doc help you clarify your questions? Provider Scope section of Providers page

  3. bibhas2 commented on Jan 11, 2018

    @bibhas2
    Author

    @kapunahelewong. The Provider Scope section of Providers page link you have posted describes how the user of a module can limit the scope of services through various means. It doesn't explain why a module itself can not have any private services. There must good reasons why a module can have private declarables but not services.

    If there are no good reasons and things are as they are for historical reasons please just state the same.

  4. kapunahelewong commented on Jan 11, 2018

    @kapunahelewong
    Contributor

    Hm, I think you might be interested in a doc I'm currently working on with Misko but isn't quite ready yet. It is about injector trees. It's in its early stages, but will probably go in the NgModules section when it's ready. I think it will be entitled something like "Injectors" or "Injector Trees". Here's a gist of the work in progress. It's pretty rough, but maybe it'll help.

    I'm not an expert on services...@gkalpak, would you be able to enlighten us? I think you can actually have scoped (to a module) services, but the caveat is....? (@bibhas2 you've taken me to the precipice of my knowledge :) ).

  5. gkalpak commented on Jan 11, 2018

    @gkalpak
    Member

    I am not really sure myself. @mhevery or @IgorMinar should have a better idea 😃

    If I had to guess, I would say that modules were introduced for grouping components/directives rather than services, because there was not a need for that.

    Services are accessed via their identifier (e.g. a type or token), so access can be restricted by restricting access to the identifier. Components/Directives on the other hand are identified (e.g. in a template) by their selector (a string), so you need a different way to disambiguate.

    (Also, keep in mind that not all modules have their own injector, so in order to support private services, non-trivial changesto the DI implementation would be needed.)

    (But, like I said, I am stabbing in the dark; there could be totally different reasons or caveats 😁

  6. bibhas2 commented on Jan 12, 2018

    @bibhas2
    Author

    OK, I have a better handle over the topic and can provide a few suggestions. Our overarching goal here is to show people how to create services that are private to a feature module. This is actually possible. These are the steps. They are actually mentioned in the How do I restrict service scope to a module? section of the FAQ. But honestly it appears very hidden and hard to decipher. So here it is in my own language: :-)

    1. Create the service class as usual.
    2. Do not add the service class to the providers list of the @NgModuleannotation of the feature module class.
    3. Add the service class instead to the providers list of each component within the feature module that needs to use the service.

    Now the service will be available within the feature module only and not to the the users of that module.

  7. added this to the needsTriage milestone on Feb 26, 2018
  8. added
    featureLabel used to distinguish feature request from other issues
    on May 22, 2018
  9. modified the milestones: needsTriage, Backlog on May 22, 2018
  10. jenniferfell commented on May 22, 2018

    @jenniferfell
    Contributor

    docsarea=ngmodules

  11. kapunahelewong commented on May 23, 2018

    @kapunahelewong
    Contributor

    @bibhas2 we can limit services to a module by providing them in the component, as discussed in Should I add other providers to a module or a component?
    but generally, it's better to do this by providing the service in a lazy loaded NgModule. When we provide a service in a Component, we run the risk of creating multiple instances of the service. Sometimes, we may need multiple instances, but generally, we want one. To limit access to the service, it is wiser to use lazy loading. I'll work on that FAQ.

  12. kapunahelewong commented on Jan 16, 2019

    @kapunahelewong
    Contributor

    Closing as the PR was merged. @bibhas2 if you still have questions, let me know as I'm happy to continue the conversation.

  13. angular-automatic-lock-bot commented on Sep 14, 2019

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  14. locked and limited conversation to collaborators on Sep 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

featureLabel used to distinguish feature request from other issuesfreq1: low

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions