diff --git a/lib/di_container.dart b/lib/di_container.dart new file mode 100644 index 0000000..27ac8c0 --- /dev/null +++ b/lib/di_container.dart @@ -0,0 +1,75 @@ +import 'package:dart_di/resolvers/resolving_context.dart'; + +/** + * Контейнер - это объект, которой хранит все резолверы зависимостей. + */ +class DiContainer { + final DiContainer _parent; + + final _resolvers = {}; + + DiContainer([this._parent]); + +/** + * Добавляет resolver зависимостей типа [T] в контейнер. + * Обратите внимание, что перезапись значений внутри одного контейнера запрещена. + * @return - возвращает [ResolvingContext] или [StateError] + */ + ResolvingContext bind() { + var context = ResolvingContext(this); + if (hasInTree()) { + throw StateError( + 'Dependency of type `$T` is already exist in containers tree'); + } + + _resolvers[T] = context; + return context; + } + + /** + * Возвращает разрешенную зависимость, определенную параметром типа [T]. + * Выдает [StateError], если зависимость не может быть разрешена. + * Если вы хотите получить [null], если зависимость не может быть разрешена, + * то используйте вместо этого [tryResolve] + * @return - возвращает объект типа [T] или [StateError] + */ + T resolve() { + var resolved = tryResolve(); + if (resolved != null) { + return resolved; + } else { + throw StateError( + 'Can\'t resolve dependency `$T`. Maybe you forget register it?'); + } + } + + /** + * Возвращает разрешенную зависимость типа [T] или null, если она не может быть разрешена. + */ + T tryResolve() { + var resolver = _resolvers[T]; + if (resolver != null) { + return resolver.resolve(); + } else { + return _parent?.tryResolve(); + } + } + + /** + * Возвращает true, если у этого контейнера есть средство разрешения зависимостей для типа [T]. + * Если вы хотите проверить его для всего дерева контейнеров, используйте вместо него [hasInTree]. + * @return - возвращает булево значение + */ + bool has() { + return _resolvers.containsKey(T); + } + +/** + * Возвращает true, если контейнер или его родители содержат средство разрешения зависимостей для типа [T]. + * Если вы хотите проверить его только для этого контейнера, используйте вместо него [has]. + * @return - возвращает булево значение + */ + bool hasInTree() { + return has() || (_parent != null && _parent.hasInTree()); + } +} diff --git a/lib/resolvers/resolving_context.dart b/lib/resolvers/resolving_context.dart new file mode 100644 index 0000000..1484013 --- /dev/null +++ b/lib/resolvers/resolving_context.dart @@ -0,0 +1,124 @@ +import 'package:dart_di/di_container.dart'; +import 'package:dart_di/resolvers/resolver.dart'; + +class ResolvingContext extends Resolver { + DiContainer _container; + + // Корневой резолвер + Resolver _resolver; + + ResolvingContext(this._container); + +/** + * Разрешает зависимость типа [T] + * @return - возвращает объект типа [T] + */ + @override + T resolve() { + // TODO: implement resolve + throw UnimplementedError(); + } + + /** + * Добавляет резолвер в качестве корневого резолвера + * С помощью этого метода вы можете добавить любой + * пользовательский резолвер + */ + ResolvingContext toResolver(Resolver resolver) { + // TODO: implement toResolver + throw UnimplementedError(); + } + + /** + * Создать резолвер значения + */ + ResolvingContext toValue(T value) { + // TODO: implement toValue + throw UnimplementedError(); + } + + /** + * Преобразователь в сингелтон + */ + ResolvingContext asSingleton() { + // TODO: implement asSingleton + throw UnimplementedError(); + } + + /** + * Создать фабричный resolver без каких-либо зависимостей + */ + ResolvingContext toFactory(TImpl Function() factory) { + // TODO: implement toFactory + throw UnimplementedError(); + } + + /** + * Создать фабричный resolver с 1 зависимостью от контейнера + */ + ResolvingContext toFactory1(T Function(T1) factory) { + // TODO: implement toFactory1 + throw UnimplementedError(); + } + + /** + * Создать фабричный resolver с 2 зависимостями от контейнера + */ + ResolvingContext toFactory2(T Function(T1, T2) factory) { + // TODO: implement toFactory2 + throw UnimplementedError(); + } + + /** + * Создать фабричный resolver с 3 зависимостями от контейнера + */ + ResolvingContext toFactory3(T Function(T1, T2, T3) factory) { + // TODO: implement toFactory3 + throw UnimplementedError(); + } + + /** + * Создать фабричный resolver с 4 зависимостями от контейнера + */ + ResolvingContext toFactory4( + T Function(T1, T2, T3, T4) factory) { + // TODO: implement toFactory4 + throw UnimplementedError(); + } + + /** + * Создать фабричный resolver с 5 зависимостями от контейнера + */ + ResolvingContext toFactory5( + T Function(T1, T2, T3, T4, T5) factory) { + // TODO: implement toFactory5 + throw UnimplementedError(); + } + + /** + * Создать фабричный resolver с 6 зависимостями от контейнера + */ + ResolvingContext toFactory6( + T Function(T1, T2, T3, T4, T5, T6) factory) { + // TODO: implement toFactory6 + throw UnimplementedError(); + } + + /** + * Создать фабричный resolver с 7 зависимостями от контейнера + */ + ResolvingContext toFactory7( + T Function(T1, T2, T3, T4, T5, T6, T7) factory) { + // TODO: implement toFactory7 + throw UnimplementedError(); + } + + /** + * Создать фабричный resolver с 8 зависимостями от контейнера + */ + ResolvingContext toFactory8( + T Function(T1, T2, T3, T4, T5, T6, T7, T8) factory) { + // TODO: implement toFactory8 + throw UnimplementedError(); + } +}