AppController for AngualrDart&Flutter

Issue

I am writing a project in AngularDart and flutter, which are sharing common codes. I have AppController, which will handles all the logic business codes, being used in most components:

class AppController {
  AppController(this.serviceOne, this.serviceTwo...);
}

Now I am writing AngularDart. I have two options:

  1. Use DI, pass AppController, serviceOne, serviceTwo as providers into bootstrap. I am not sure whether I should mark these classes as injectable. And I heard that flutter doesn’t quite support injectable. And I am a newbie in Dependency injection, not sure how to implement it.

Code 1.1:

  bootstrap(AppComponent, [
    new Provider(
      AppController,
      useValue: new AppController(
        new ServiceA(),
        new ServiceB(),
        ....
      ),
    ),
  ]);

Code 1.2:

  bootstrap(AppComponent, [
    AppController,
    ServiceA,
    ServiceB,
  ]);

Code 1.3:

  // From Günter Zöchbauer's answer
  createAppFactory(ServiceA sa, ServiceB sb) => new AppController(sa, sb);
  bootstrap(AppComponent, [
    new Provider<AppController>(
      useFactory: createAppFactory,
      deps: [ServiceA, ServiceB]          
    ),
  ]);
  1. Pass into AppComponent and sub-components as @input level by level. This is simple but doesn’t look elegant.
class AppComponent(AppController controller) {
}

class subComponent() {
     @input 
     AppController _controller
}  
  1. Other better options?

And I am also thinking, if we use appController to handle the business logic layer, and let the platform codes implement only the widget. The services are defined in the common codes. Can I just create the services inside appController and don’t let platform codes touch it. In other words, platforms codes uses the common code only through appController, and the services are created internally in the appController.

Solution

If you add the @Injectable() annotation, you can’t use the code in Flutter anymore because it ties the code to dart:html through Angular.

You need to create the service without @Injectable() and then add a wrapper for Angular with the annotation.

in shared_code/lib/foo_service.dart

class FooService {
  BarService bar; 
  FooService(this.bar);
}

in angular_code/lib/foo_service.dart

import 'package:shared_code/foo_service.dart' as shared;

@Injectable()
class FooService extends shared.FooService {
  FooService(BarService bar) : super(bar);
} 

I think I saw it mentioned that the Angular team was discussing about whether they can get rid of @Injectable(). That would make this much easier.

Another way would be to use factory providers to not require @Injectable()

FooService createFooService(BarService bar) => new FooService(bar);
FooService createBarService() => new BarService();

providers: const [
  const FactoryProvider(FooService, createFooService, deps: const [BarService]), 
  const FactoryProvider(BarService, createBarService)] 

Answered By – Günter Zöchbauer

Answer Checked By – Timothy Miller (FlutterFixes Admin)

Leave a Reply

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