Angel
1.x
1.x
  • Introduction
  • Example Projects
  • Awesome Angel
  • 1.1.0 Migration Guide
  • Social
    • Angel on Gitter
    • Angel on Medium
    • Angel on YouTube
  • The Basics
    • Installation & Setup
      • Without the Boilerplate
    • Requests & Responses
    • Dependency Injection
    • Basic Routing
    • Request Lifecycle
    • Middleware
    • Controllers
    • Handling File Uploads
    • Using Plug-ins
    • Rendering Views
    • REST Client
    • Testing
    • Error Handling
    • Pattern Matching and Parameter
    • Command Line
  • Flutter
    • Writing a Chat App
    • Flutter helper widgets
  • Services
    • Service Basics
    • TypedService
    • In-Memory
    • Custom Services
    • Hooks
      • Bundled Hooks
    • Database-Agnostic Relations
    • Database Adapters
      • MongoDB
      • RethinkDB
      • JSON File-based
  • Plug-ins
    • Authentication
    • Configuration
    • Diagnostics & Logging
    • Reverse Proxy
    • Service Seeder
    • Static Files
    • Validation
    • Websockets
    • Server-sent Events
    • Toggle-able Services
  • Middleware/Finalizers
    • CORS
    • Response Compression
    • Security
    • File Upload Security
    • shelf Integration
    • User Agents
    • Pagination
    • Range, If-Range, Accept-Ranges support
  • PostgreSQL ORM
    • Model Serialization
    • Query Builder + ORM
    • Migrations
  • Deployment
    • Running in Isolates
    • Configuring SSL
    • HTTP/2 Support
    • Ubuntu and nginx
    • AppEngine
    • Production Mode
  • Front-end
    • Mustache Templates
    • Jael template engine
      • Github
      • Basics
      • Custom Elements
      • Strict Resolution
      • Directive: declare
      • Directive: for-each
      • Directive: extend
      • Directive: if
      • Directive: include
      • Directive: switch
    • compiled_mustache-based engine
    • html_builder-based engine
    • Markdown template engine
    • Using Angel with Angular
  • Advanced
    • API Documentation
    • Contribute to Angel
    • Scaling & Load Balancing
    • Standalone Router
    • Writing a Plugin
    • Task Engine
    • Hot Reloading
    • Real-time polling
Powered by GitBook
On this page
  • Adding a Singleton
  • In Routes and Controllers
  • Dependency-Injected Controllers
  1. The Basics

Dependency Injection

PreviousRequests & ResponsesNextBasic Routing

Last updated 6 years ago

Angel uses Emil Persson's for DI. Dependency injection makes it easier to build applications with multiple moving parts, because logic can be contained in one location and reused at another place in your application.

Adding a Singleton

class MyPlugin extends AngelPlugin {
  @override
  call(Angel app) async {
    app.container.singleton(new SomeClass("foo"));
  }
}

class SomeClass {
  String text;
  SomeClass(this.text);
}

You can also inject within a RequestContext.

// Inject types
req.inject(Todo, someTodoInstanceSingleton);

// Or by name
req.inject('database', await databaseProvider.connect('proto://conn-string'));

// Inject into *every* request
app.inject('foo', bar);

In Routes and Controllers

app.get("/some/class/text", (SomeClass singleton) => singleton.text); // Always "foo"

app.post("/foo", (SomeClass singleton, {Foo optionalInjection});

@Expose("/my/controller")
class MyController extends Controller {

  @Expose("/bar")
  // Inject classes from container, request parameters or the request/response context :)
  bar(SomeClass singleton, RequestContext req) => "${singleton.text} bar"; // Always "foo bar"

  @Expose("/baz")
  baz({Foo optionalInjection});
}

As you can imagine, this is very useful for managing things such as database connections.

configureServer(Angel app) async {
  var db = new Db("mongodb://localhost:27017/db");
  await db.open();
  app.container.singleton(db);
}

@Expose("/users")
class ApiController extends Controller {
  @Expose("/:id")
  fetchUser(String id, Db db) => db.collection("users").findOne(where.id(new ObjectId.fromHexString(id)));
}

Dependency-Injected Controllers

Controllers have dependencies injected without any additional configuration by you. However, you might want to inject dependencies into the constructor of your controller.

@Expose('/controller')
class MyController {
  final AngelAuth auth;
  final Db db;

  MyController(this.auth, this.db);

  @Expose('/login')
  login() => auth.authenticate('local');
}

main() async {
  // At some point in your application, register necessary dependencies as singletons...
  app.container.singleton(auth);
  app.container.singleton(db);

  // Create the controller with injected dependencies
  await app.configure(app.container.make(MyController));
}
Container