NgRx Auto-Entity
Primary version
Primary version
  • NgRx Auto-Entity
  • Getting Started
    • Installation
    • Quick Start
    • Use your State!
      • Enhancing your Facade
      • Simplify your Component
    • From Scratch
      • App Interfaces
      • App Reducer
      • App State Module
      • Entity Model
      • Entity State
      • Update App State
      • Entity Service
      • Update App Module
  • Advanced Topics
    • Advanced Usage
      • Paradigm Changes
        • Models
        • Services
        • Service Providers
      • Taking Control
        • Integrating Custom Effects
      • Building Your Entities
        • Entity Names
        • Sort Comparers
        • Data Transforms
      • Building Your Entity States
        • The buildState() function
        • The buildFeatureState() function
        • The IEntityState Interface
        • The Selector Map
      • Generic Actions
        • Actions Now
        • Reusable Generic Actions
        • Custom Criteria
        • Loading Actions
          • Loading Entities
          • Loading Pages
          • Loading Ranges
        • Optional Loading
        • CURD Actions
        • Utility Actions
      • Correlation
      • Common Selectors
        • Exporting Selectors
      • Extra Selectors
      • Custom Selectors
        • Adding to Facades
        • Using Custom Selectors
      • Custom Effects
        • Composing Actions
        • Workflows
    • Leveraging Facades
      • Preparing Facades
      • The Interface: Selections
        • Using Facade Selections
        • Simplifying Further
      • The Interface: Activities
        • Using Facade Activities
      • So Little Code!
    • Utility Functions
      • Prototyping your Entities
        • Entity Making Performance
      • Entity Name Utilities
      • Entity Key Utilities
      • Entity Comparers
  • Examples
    • Sample Application
      • App Module
      • State
      • Models
      • Services
      • Facades
      • Container Components
      • Presentation Components
      • Modal Component
  • Documentation
    • Reference
  • Extras
    • Github Link
Powered by GitBook
On this page
  • Mapping Model to Service
  • Efficiency with Service Mappings
  • Minification and Service Lookup
Export as PDF
  1. Advanced Topics
  2. Advanced Usage
  3. Paradigm Changes

Service Providers

Understand the changes to defining service providers

For most Angular applications, services can be provided very simply, simply by including the class in the array of providers in your module. With NgRX Auto-Entity, due to its dynamic nature we must change how services for entities are provided a little bit.

Mapping Model to Service

Instead of registering the service itself directly, we must instead register the model class as the provider, and map it to an entity service via the useClass option. Like so:

src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { NgrxAutoEntityModule } from '@briebug/ngrx-auto-entity';

import { AppComponent } from './app.component';

import { Customer } from 'models';
import { CustomerService } from 'services/customer.service';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, NgrxAutoEntityModule],
  providers: [
    { provide: Customer, useClass: CustomerService }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

When dispatching an action, the model class is specified as the first parameter, and as such the model class is the only thing NgRX Auto-Entity can use to look up the necessary service provider. By mapping the model class to the service class, you are leveraging a standard Angular paradigm to support dynamic service lookup at runtime.

Efficiency with Service Mappings

Auto-Entity makes it possible to reuse a single smart entity service with multiple entities. This approach allows another reduction in developer effort, requiring an initial effort up front to implement the entity service, however over the lifetime of the application that single service may be used countless times for countless entities.

Mapping each entity to a service may not be the most efficient approach. Each provider will be a new instance of the entity service. In order to supply a single service instance you can use a factory with another provider.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { NgrxAutoEntityModule } from '@briebug/ngrx-auto-entity';

import { AppComponent } from './app.component';

import { Customer } from 'models';
import { Product } from 'models';
import { Order } from 'models';
import { LineItem } from 'models';
import { EntityService } from 'services/entity.service';

export function provideEntityService(service: EntityService) {
  return service;
}

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, NgrxAutoEntityModule],
  providers: [
    EntityService,
    { provide: Customer, useFactory: provideEntityService, deps: [EntityService] },
    { provide: Product, useFactory: provideEntityService, deps: [EntityService] },
    { provide: Order, useFactory: provideEntityService, deps: [EntityService] },
    { provide: LineItem, useFactory: provideEntityService, deps: [EntityService] },    
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Minification and Service Lookup

To ensure that auto-entity's service lookup for a given identifier of application state will work even when your code has been minified/uglified, run through AoT, optimized, etc. we require that a string name for each model be defined with the Entity decorator. This name is used instead of the actual runtime class name, thus guaranteeing that even if the class name (and therefor constructor.name) is changed during minification, auto-entity will still function properly.

NgRx Auto-Entity will still attempt to utilize the model class's constructor.name in the event that a model has not been decorated with the @Entity decorator. This can allow simple, rapid prototyping of an auto-entity application when run in development mode. However without proper decoration, minified, optimized, aot production code will not function properly.

A future version of NgRx Auto-Entity may change this behavior in favor of requiring that every entity always be decorated with @Entity. As such, it is encouraged that all entity models always be properly decorated at all times.

PreviousServicesNextTaking Control

Last updated 4 years ago