Using $injector.invoke() for dependency injection

Loading

AngularJS provides a powerful Dependency Injection (DI) mechanism to manage dependencies efficiently. One of the lesser-known but powerful methods of dependency injection is $injector.invoke(). It allows you to dynamically resolve and inject dependencies at runtime, making it useful for scenarios where dependencies need to be determined dynamically.


1. What is $injector.invoke()?

The $injector.invoke() method in AngularJS is used to invoke a function with its dependencies injected automatically. It is primarily used when you need to dynamically inject dependencies or execute a function within a specific context.

Syntax

$injector.invoke(functionName, self, locals);
ParameterDescription
functionNameThe function to invoke (can be an inline function or reference to an existing function)
self(Optional) The this context for the function
locals(Optional) A map of dependencies that override default AngularJS DI

2. Why Use $injector.invoke()?

Dynamic Dependency Injection – Inject dependencies at runtime.
Avoid Hardcoded Dependencies – Useful for plugins or dynamically created components.
Unit Testing & Mocking – Easily override dependencies for testing.
Extending AngularJS Applications – Use $injector.invoke() for modular applications.


3. Example Usage of $injector.invoke()

Example 1: Injecting Dependencies Dynamically

var app = angular.module('myApp', []);

app.controller('MainController', function($scope, $injector) {
var dependencies = function($http, $timeout) {
console.log("Dependencies injected: ", $http, $timeout);
};

// Using $injector.invoke() to inject dependencies
$injector.invoke(dependencies);
});

What happens?

  • $injector.invoke() automatically injects $http and $timeout into dependencies function.
  • No need to explicitly list dependencies in the controller.

Example 2: Injecting Dependencies with Locals

app.controller('MainController', function($scope, $injector) {
var customFunction = function($http, customService) {
console.log("Injected: ", $http, customService);
};

var mockService = { name: "Mocked Service" };

// Using $injector.invoke() and overriding customService with a mock
$injector.invoke(customFunction, null, { customService: mockService });
});

Why use locals?

  • The locals parameter lets you override dependency injection.
  • Here, customService is injected with a mock object instead of a real service.

4. Using $injector.invoke() Inside a Service

You can use $injector.invoke() inside a service to dynamically inject and execute functions.

app.factory('MyService', function($injector) {
return {
runFunction: function(fn) {
return $injector.invoke(fn);
}
};
});

app.controller('MainController', function($scope, MyService) {
function sampleFunction($http) {
console.log("Service Injected: ", $http);
}

MyService.runFunction(sampleFunction);
});

What Happens?

  • MyService.runFunction() takes any function and injects its dependencies dynamically.

5. $injector.invoke() vs $injector.get()

Feature$injector.invoke()$injector.get()
Inject DependenciesYes (function-based)No (direct service retrieval)
Supports Locals OverrideYesNo
Use CaseDynamically invoke a function with dependenciesRetrieve a service instance

Example of $injector.get()

var $httpService = $injector.get('$http'); // Directly retrieves $http service

When to Use What?

  • Use $injector.invoke() when injecting dependencies into a function.
  • Use $injector.get() when retrieving a single service.

6. Real-World Use Cases of $injector.invoke()

1. Plugin-based Architecture

  • Allows dynamically loading and executing components based on user selection.

2. Conditional Dependency Injection

  • Inject services only when required, optimizing performance.

3. Unit Testing

  • Override dependencies with mocks using the locals parameter.

4. Dynamically Configuring Controllers

  • Invoke controllers dynamically without hardcoding dependencies.

Leave a Reply

Your email address will not be published. Required fields are marked *