Skip to content

Commit bcffc85

Browse files
Updating for 3.0.0
1 parent 42ab3f4 commit bcffc85

13 files changed

+309
-147
lines changed

README.md

Lines changed: 171 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,199 +1,226 @@
11
# Dependency initializer
2-
DependencyInitializer is a convenient and understandable contract for initializing dependencies for further use.\
3-
The main goal of this utility is to provide a clear assembly of a dependency container with initialization steps.\
2+
DependencyInitializer is a convenient and understandable contract for initializing dependencies.\
3+
The main goal is to provide a clear assembly of a dependency container with initialization steps.\
44
Advantages:
55
1) Convenient configuration - creating your own initialization steps and filling the initialization process;
6-
2) Error handling and providing initialization steps;
7-
3) Re-initialization for steps that were created as repeated, for example, for changing the environment.
6+
2) Parallel computation of isolated steps in separate isolates;
7+
3) Error handling;
8+
4) Re-initialization for steps that were created as repeated, for example, for changing the environment.
89

910
# Use cases
1011
Dart - run the initializer, get a dependency container and use it during the lifetime of the program.
1112
Flutter - run the initializer, get a dependency container, place it in the InheritedWidget, and then in any widget get it through the BuildContext using ```final dependencies = context.read<MyDependencyContainer>();```.
1213

1314
Important points for full use:
1415
1) Initialization steps imply not only filling the initialization process, but also the possibility of your custom checks related to business logic requests.
15-
2) Do not forget that in case of an initialization error, you can show the error screen, and by passing the result to this widget, you can restart the initialization process using reRun.
16+
2) Do not forget that in case of an initialization error, you can show the error screen, and by passing the result to this widget, you can restart the initialization process using runRepeat.
1617
Identically as for a successful launch, a similar scenario works for a test application, in particular for changing the environment without restarting the application.
1718

1819
# Usage
19-
1) Prepare list of initialize steps.
20+
## Container
21+
Create a container that will be the final result of all initialization:
2022
```dart
21-
final List<InitializationStep<MyProcess>> coresteps = [
22-
InitializationStep(
23-
title: "Config",
24-
initialize: (
25-
MyProcess process,
26-
) =>
27-
process.config = const MyConfig(),
28-
),
29-
];
30-
final List<InitializationStep<MyProcess>> datasteps = [
31-
InitializationStep(
32-
title: "HttpClient",
33-
initialize: (
34-
MyProcess process,
35-
) =>
36-
process.client = MyHttpClient(
37-
config: process.config!,
38-
),
39-
),
40-
InitializationStep(
41-
title: "Api",
42-
initialize: (
43-
MyProcess process,
44-
) =>
45-
process.api = MyApi(
46-
client: process.client!,
47-
),
48-
),
49-
InitializationStep(
50-
title: "Dao",
51-
initialize: (
52-
MyProcess process,
53-
) =>
54-
process.dao = MyDao(
55-
config: process.config!,
56-
),
57-
),
58-
InitializationStep(
59-
title: "Storage",
60-
initialize: (
61-
MyProcess process,
62-
) =>
63-
process.storage = MyStorage(
64-
config: process.config!,
65-
),
66-
),
67-
InitializationStep(
68-
title: "Repository",
69-
initialize: (
70-
MyProcess process,
71-
) =>
72-
process.repository = MyRepository(
73-
api: process.api!,
74-
dao: process.dao!,
75-
storage: process.storage!,
76-
),
77-
),
78-
];
79-
final List<InitializationStep<MyProcess>> blocsteps = [
80-
InitializationStep(
81-
title: "Bloc",
82-
initialize: (
83-
MyProcess process,
84-
) =>
85-
process.bloc = MyBloc(
86-
repository: process.repository!,
87-
),
88-
),
89-
];
23+
final class Dependency {
24+
const Dependency({
25+
required this.environment,
26+
required this.repository,
27+
required this.initialCatFact,
28+
});
29+
30+
final Environment environment;
31+
final Repository repository;
32+
final CatFact initialCatFact;
33+
}
9034
```
35+
The container can contain not only dependency entities, but also the original domain models for business logic.
36+
## Process
37+
Create a process that will gradually fill up.
38+
```dart
39+
final class InitializationProcess extends DependencyInitializationProcess<Dependency> {
40+
Environment? environment;
41+
Client? client;
42+
Api? api;
43+
Database? database;
44+
Repository? repository;
9145
92-
2) Create initializer and start initialize process:
46+
/// Converts isolated results into a container of type [T].
47+
///
48+
/// [isolatedResults] - A map containing the results of isolated initialization steps.
49+
/// Returns a container of type [T] that contains all initialized dependencies.
50+
@override
51+
Dependency toContainer(
52+
Map<dynamic, dynamic> isolatedResults,
53+
) => Dependency(
54+
environment: environment!,
55+
repository: repository!,
56+
initialCatFact: isolatedResults['InitialCatFact'],
57+
);
58+
}
59+
```
60+
## Steps
61+
[DependencyInitializationStepType](https://github.com/ivangalkindeveloper/dependency_initializer/blob/master/lib/src/dependency_initialization_step_type.dart) - step execution type:
62+
simple - the step is executed once, this is useful for example for initializing Firebase, database and other integration packages.
63+
repeatable - the step is executed and remembered for further repeated execution when calling re-initialization using the runRepeat function.
64+
[InitializationStep](https://github.com/ivangalkindeveloper/dependency_initializer/blob/master/lib/src/dependency_initialization_step.dart) - async/async execution step in the current main isolate.
65+
[IsolatedInitializationStep](https://github.com/ivangalkindeveloper/dependency_initializer/blob/master/lib/src/dependency_initialization_step.dart) - sync/async execution step in the new parallel isolate.
66+
Prepare list of initialize steps:
9367
```dart
94-
final DependencyInitializer initializer = DependencyInitializer<MyProcess, MyResult>(
95-
creteProcess: () => MyProcess(),
96-
steps: [
97-
...coresteps,
98-
...datasteps,
99-
...blocsteps,
100-
],
101-
onSuccess: (
102-
DependencyInitializationResult<MyProcess, MyResult> initializationResult,
103-
Duration duration,
68+
final List<InitializationStep<MyProcess>> steps = [
69+
InitializationStep<InitializationProcess, Dependency>(
70+
title: "Data",
71+
run: (
72+
InitializationProcess process
10473
) {
105-
// Success result of initialization
106-
// For Flutter example: runApp(ApplicationWidget(result: result));
74+
process.environment = const BaseEnvironment();
75+
process.client = HttpClient(
76+
environment: process.environment!
77+
);
78+
process.api = EntityApi(
79+
client: process.client!
80+
);
81+
process.database = EntityDatabase(
82+
environment: process.environment!,
83+
);
84+
process.repository = EntityRepository(
85+
api: process.api!,
86+
database: process.database!,
87+
);
10788
},
108-
);
109-
await initializer.run();
89+
),
90+
IsolatedInitializationStep<
91+
InitializationProcess,
92+
Dependency,
93+
String,
94+
CatFact
95+
>(
96+
title: "Cat Fact",
97+
isolatedKey: "InitialCatFact",
98+
run: (InitializationProcess process) async {
99+
final CatFact initialCatFact = await process.repository!.getCatFact();
100+
return initialCatFact;
101+
},
102+
),
103+
];
104+
```
105+
## DependencyInitializer
106+
Create initializer and start initialize process:
107+
```dart
108+
DependencyInitializer<InitializationProcess, Dependency>(
109+
createProcess: () => InitializationProcess(),
110+
steps: steps,
111+
onSuccess: (
112+
DependencyInitializationResult<InitializationProcess, Dependency>
113+
result,
114+
Duration duration,
115+
) => runApp(
116+
Application(
117+
dependency: result.container,
118+
),
119+
),
120+
onError: (
121+
Object error,
122+
StackTrace stackTrace,
123+
InitializationProcess process,
124+
DependencyInitializationStep step,
125+
Duration duration,
126+
) => runApp(
127+
ErrorApplication(
128+
error: error,
129+
),
130+
),
131+
).run();
110132
```
111133

112134
# Usage examples
113135
Initializer has several use cases:
114136
1) Direct.\
115137
For example, if you want the Flutter application to show a native splash screen when it starts, and then launch the first widget.
116138
```dart
117-
final Initializer initializer = Initializer<MyProcess, MyResult>(
118-
creteProcess: () => MyProcess(),
119-
steps: steps,
120-
onSuccess: (
121-
DependencyInitializationResult<MyProcess, MyResult> initializationResult,
122-
Duration duration,
123-
) => runApp(
124-
ApplicationWidget(
125-
result: initializationResult.result,
126-
),
139+
DependencyInitializer<InitializationProcess, Dependency>(
140+
createProcess: () => InitializationProcess(),
141+
steps: steps,
142+
onSuccess: (
143+
DependencyInitializationResult<InitializationProcess, Dependency> result,
144+
Duration duration,
145+
) => runApp(
146+
Application(
147+
dependency: result.container,
127148
),
128-
onError: (
129-
Object? error,
130-
StackTrace stackTrace,
131-
MyProcess process,
132-
DependencyInitializationStep<MyProcess> step,
133-
Duration duration,
134-
) => runApp(
135-
const ApplicationErrorWidget(),
149+
),
150+
onError: (
151+
Object error,
152+
StackTrace stackTrace,
153+
InitializationProcess process,
154+
DependencyInitializationStep step,
155+
Duration duration,
156+
) => runApp(
157+
ErrorApplication(
158+
error: error,
136159
),
137-
);
138-
await initializer.run();
160+
),
161+
).run();
139162
```
140163

141164
2) With async completer.\
142165
For example, you have a widget that displays its splash screen, and this widget must be rebuilt asynchronously using the initialization compiler.
143166
```dart
144-
final Initializer initializer = Initializer<MyProcess, MyResult>(
145-
creteProcess: () => MyProcess(),
146-
steps: steps,
147-
onStart: (
148-
Completer<DependencyInitializationResult<MyProcess, MyResult>> completer,
149-
) => runApp(
150-
ApplicationWidget(
151-
completer: completer,
152-
),
167+
DependencyInitializer<InitializationProcess, Dependency>(
168+
createProcess: () => InitializationProcess(),
169+
steps: steps,
170+
onStart: (
171+
Completer<DependencyInitializationResult<MyProcess, MyResult>> completer,
172+
) => runApp(
173+
ApplicationWidget(
174+
completer: completer,
153175
),
154-
onError: (
155-
Object? error,
156-
StackTrace stackTrace,
157-
MyProcess process,
158-
DependencyInitializationStep<MyProcess> step,
159-
Duration duration,
160-
) => runApp(
161-
const ApplicationErrorWidget(),
176+
),
177+
onError: (
178+
Object error,
179+
StackTrace stackTrace,
180+
InitializationProcess process,
181+
DependencyInitializationStep step,
182+
Duration duration,
183+
) => runApp(
184+
ErrorApplication(
185+
error: error,
162186
),
163-
);
164-
await initializer.run();
187+
),
188+
).run();
165189
```
166190

167191
3) Reinitialization from result.\
168192
For example, in the runtime of a Flutter application, you need to reinitialize your new dependencies for the new environment and return the first widget of the Flutter application again.
169193
```dart
170-
await initializationResult.reRun(
194+
await result.runRepeat(
171195
steps: [
172-
InitializationStep(
173-
title: "Config",
174-
initialize: (
175-
MyProcess process,
176-
) =>
177-
process.config = AnotherConfig(),
196+
InitializationStep<InitializationProcess, Dependency>(
197+
title: "Environment",
198+
run: (
199+
InitializationProcess process
200+
) {
201+
process.environment = const NewEnvironment();
202+
},
178203
),
179-
...initializationResult.repeatSteps,
204+
...result.repeatSteps,
180205
],
181206
onSuccess: (
182-
DependencyInitializationResult<MyProcess, MyResult> initializationResult,
207+
DependencyInitializationResult<InitializationProcess, Dependency> result,
183208
Duration duration,
184209
) => runApp(
185-
ApplicationWidget(
186-
result: initializationResult.result,
210+
Application(
211+
dependency: result.container,
187212
),
188213
),
189214
onError: (
190-
Object? error,
215+
Object error,
191216
StackTrace stackTrace,
192-
MyProcess process,
193-
DependencyInitializationStep<MyProcess> step,
217+
InitializationProcess process,
218+
DependencyInitializationStep step,
194219
Duration duration,
195220
) => runApp(
196-
const ApplicationErrorWidget(),
221+
ErrorApplication(
222+
error: error,
223+
),
197224
),
198225
);
199226
```

example/lib/main.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import 'package:example/widget/error_application.dart';
88
import 'package:flutter/cupertino.dart';
99

1010
Future<void> main() =>
11-
DependencyInitializer(
11+
DependencyInitializer<InitializationProcess, Dependency>(
1212
createProcess: () => InitializationProcess(),
1313
steps: [
1414
InitializationStep<InitializationProcess, Dependency>(
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1+
/// Abstract class that represents a dependency initialization process.
2+
///
3+
/// This class defines the contract for creating a container from isolated results
4+
/// during the dependency initialization process.
15
abstract class DependencyInitializationProcess<T> {
26
const DependencyInitializationProcess();
37

8+
/// Converts isolated results into a container of type [T].
9+
///
10+
/// [isolatedResults] - A map containing the results of isolated initialization steps.
11+
/// Returns a container of type [T] that contains all initialized dependencies.
412
T toContainer(Map<dynamic, dynamic> isolatedResults);
513
}

0 commit comments

Comments
 (0)