mirror of
https://github.com/pese-git/cherrypick.git
synced 2026-01-24 05:25:19 +00:00
refactored di library.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
library dart_di;
|
||||
|
||||
export 'package:dart_di/di_container.dart';
|
||||
export 'package:dart_di/resolvers/resolvers.dart';
|
||||
export 'package:dart_di/resolvers/resolving_context.dart';
|
||||
export 'package:dart_di/scope.dart';
|
||||
export 'package:dart_di/module.dart';
|
||||
export 'package:dart_di/binding.dart';
|
||||
export 'package:dart_di/di.dart';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:dart_di/experimental/scope.dart';
|
||||
import 'package:dart_di/scope.dart';
|
||||
|
||||
Scope? _rootScope = null;
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
import 'package:dart_di/resolvers/resolving_context.dart';
|
||||
|
||||
/**
|
||||
* Контейнер - это объект, которой хранит все резолверы зависимостей.
|
||||
*/
|
||||
class DiContainer {
|
||||
final DiContainer? _parent;
|
||||
|
||||
final _resolvers = <Type, ResolvingContext>{};
|
||||
|
||||
DiContainer([this._parent]);
|
||||
|
||||
/**
|
||||
* Добавляет resolver зависимостей типа [T] в контейнер.
|
||||
* Обратите внимание, что перезапись значений внутри одного контейнера запрещена.
|
||||
* @return - возвращает [ResolvingContext] или [StateError]
|
||||
*/
|
||||
ResolvingContext<T> bind<T>() {
|
||||
var context = ResolvingContext<T>(this);
|
||||
if (hasInTree<T>()) {
|
||||
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<T>() {
|
||||
var resolved = tryResolve<T>();
|
||||
if (resolved != null) {
|
||||
return resolved;
|
||||
} else {
|
||||
throw StateError(
|
||||
'Can\'t resolve dependency `$T`. Maybe you forget register it?');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает разрешенную зависимость типа [T] или null, если она не может быть разрешена.
|
||||
*/
|
||||
T? tryResolve<T>() {
|
||||
var resolver = _resolvers[T];
|
||||
if (resolver != null) {
|
||||
return resolver.resolve();
|
||||
} else {
|
||||
return _parent?.tryResolve<T>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает true, если у этого контейнера есть средство разрешения зависимостей для типа [T].
|
||||
* Если вы хотите проверить его для всего дерева контейнеров, используйте вместо него [hasInTree].
|
||||
* @return - возвращает булево значение
|
||||
*/
|
||||
bool has<T>() {
|
||||
return _resolvers.containsKey(T);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает true, если контейнер или его родители содержат средство разрешения зависимостей для типа [T].
|
||||
* Если вы хотите проверить его только для этого контейнера, используйте вместо него [has].
|
||||
* @return - возвращает булево значение
|
||||
*/
|
||||
bool hasInTree<T>() {
|
||||
return has<T>() || (_parent != null && _parent!.hasInTree<T>());
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:dart_di/experimental/scope.dart';
|
||||
import 'package:dart_di/scope.dart';
|
||||
|
||||
abstract class Factory<T> {
|
||||
T createInstance(Scope scope);
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:dart_di/experimental/binding.dart';
|
||||
import 'package:dart_di/experimental/scope.dart';
|
||||
import 'package:dart_di/binding.dart';
|
||||
import 'package:dart_di/scope.dart';
|
||||
|
||||
/// RU: Класс Module является основой для пользовательских модулей.
|
||||
/// Этот класс нужен для инициализации [Scope].
|
||||
@@ -1,15 +0,0 @@
|
||||
import 'package:dart_di/resolvers/resolver.dart';
|
||||
|
||||
/**
|
||||
* Разрешает зависимость для фабричной функции
|
||||
*/
|
||||
class FactoryResolver<T> extends Resolver<T> {
|
||||
final T Function() _factory;
|
||||
|
||||
FactoryResolver(this._factory);
|
||||
|
||||
@override
|
||||
T resolve() {
|
||||
return _factory();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Resolver - это абстракция, которая определяет,
|
||||
* как контейнер будет разрешать зависимость
|
||||
*/
|
||||
abstract class Resolver<T> {
|
||||
/**
|
||||
* Разрешает зависимость типа [T]
|
||||
* @return - возвращает объект типа [T]
|
||||
*/
|
||||
T? resolve();
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
/// Resolvers определяет, как разрешить зависимость для контейнера
|
||||
library resolvers;
|
||||
|
||||
export 'resolver.dart';
|
||||
export 'factory_resolver.dart';
|
||||
export 'value_resolver.dart';
|
||||
export 'singelton_resolver.dart';
|
||||
@@ -1,172 +0,0 @@
|
||||
import 'package:dart_di/di_container.dart';
|
||||
import 'package:dart_di/resolvers/factory_resolver.dart';
|
||||
import 'package:dart_di/resolvers/resolver.dart';
|
||||
import 'package:dart_di/resolvers/singelton_resolver.dart';
|
||||
import 'package:dart_di/resolvers/value_resolver.dart';
|
||||
|
||||
class ResolvingContext<T> extends Resolver {
|
||||
/// Корневой резолвер
|
||||
Resolver<T> get resolver {
|
||||
return _resolver as Resolver<T>;
|
||||
}
|
||||
|
||||
DiContainer _container;
|
||||
|
||||
late Resolver _resolver;
|
||||
|
||||
ResolvingContext(this._container);
|
||||
|
||||
/**
|
||||
* Разрешает зависимость типа [T]
|
||||
* @return - возвращает объект типа [T]
|
||||
*/
|
||||
@override
|
||||
T resolve() {
|
||||
_verify();
|
||||
return _resolver.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавляет резолвер в качестве корневого резолвера
|
||||
* С помощью этого метода вы можете добавить любой
|
||||
* пользовательский резолвер
|
||||
*/
|
||||
ResolvingContext<T> toResolver<TImpl extends T>(Resolver<TImpl> resolver) {
|
||||
_resolver = resolver;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать резолвер значения
|
||||
*/
|
||||
ResolvingContext<T> toValue<TImpl extends T>(T value) {
|
||||
Resolver<TImpl> resolver = ValueResolver(value as TImpl);
|
||||
return toResolver<TImpl>(resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Преобразователь в сингелтон
|
||||
*/
|
||||
ResolvingContext<T> asSingleton() {
|
||||
return toResolver(SingletonResolver<T>(resolver));
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать фабричный resolver без каких-либо зависимостей
|
||||
*/
|
||||
ResolvingContext<T> toFactory<TImpl extends T>(TImpl Function() factory) {
|
||||
Resolver<TImpl> resolver = FactoryResolver<TImpl>(factory);
|
||||
return toResolver(resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать фабричный resolver с 1 зависимостью от контейнера
|
||||
*/
|
||||
ResolvingContext<T> toFactory1<T1>(T Function(T1) factory) {
|
||||
Resolver<T> resolver =
|
||||
FactoryResolver<T>(() => factory(_container.resolve<T1>()));
|
||||
return toResolver(resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать фабричный resolver с 2 зависимостями от контейнера
|
||||
*/
|
||||
ResolvingContext<T> toFactory2<T1, T2>(T Function(T1, T2) factory) {
|
||||
Resolver<T> resolver = FactoryResolver<T>(
|
||||
() => factory(_container.resolve<T1>(), _container.resolve<T2>()));
|
||||
return toResolver(resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать фабричный resolver с 3 зависимостями от контейнера
|
||||
*/
|
||||
ResolvingContext<T> toFactory3<T1, T2, T3>(T Function(T1, T2, T3) factory) {
|
||||
Resolver<T> resolver = FactoryResolver<T>(() => factory(
|
||||
_container.resolve<T1>(),
|
||||
_container.resolve<T2>(),
|
||||
_container.resolve<T3>()));
|
||||
return toResolver(resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать фабричный resolver с 4 зависимостями от контейнера
|
||||
*/
|
||||
ResolvingContext<T> toFactory4<T1, T2, T3, T4>(
|
||||
T Function(T1, T2, T3, T4) factory) {
|
||||
Resolver<T> resolver = FactoryResolver<T>(() => factory(
|
||||
_container.resolve<T1>(),
|
||||
_container.resolve<T2>(),
|
||||
_container.resolve<T3>(),
|
||||
_container.resolve<T4>()));
|
||||
return toResolver(resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать фабричный resolver с 5 зависимостями от контейнера
|
||||
*/
|
||||
ResolvingContext<T> toFactory5<T1, T2, T3, T4, T5>(
|
||||
T Function(T1, T2, T3, T4, T5) factory) {
|
||||
Resolver<T> resolver = FactoryResolver<T>(() => factory(
|
||||
_container.resolve<T1>(),
|
||||
_container.resolve<T2>(),
|
||||
_container.resolve<T3>(),
|
||||
_container.resolve<T4>(),
|
||||
_container.resolve<T5>()));
|
||||
return toResolver(resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать фабричный resolver с 6 зависимостями от контейнера
|
||||
*/
|
||||
ResolvingContext<T> toFactory6<T1, T2, T3, T4, T5, T6>(
|
||||
T Function(T1, T2, T3, T4, T5, T6) factory) {
|
||||
Resolver<T> resolver = FactoryResolver<T>(() => factory(
|
||||
_container.resolve<T1>(),
|
||||
_container.resolve<T2>(),
|
||||
_container.resolve<T3>(),
|
||||
_container.resolve<T4>(),
|
||||
_container.resolve<T5>(),
|
||||
_container.resolve<T6>()));
|
||||
return toResolver(resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать фабричный resolver с 7 зависимостями от контейнера
|
||||
*/
|
||||
ResolvingContext<T> toFactory7<T1, T2, T3, T4, T5, T6, T7>(
|
||||
T Function(T1, T2, T3, T4, T5, T6, T7) factory) {
|
||||
Resolver<T> resolver = FactoryResolver<T>(() => factory(
|
||||
_container.resolve<T1>(),
|
||||
_container.resolve<T2>(),
|
||||
_container.resolve<T3>(),
|
||||
_container.resolve<T4>(),
|
||||
_container.resolve<T5>(),
|
||||
_container.resolve<T6>(),
|
||||
_container.resolve<T7>()));
|
||||
return toResolver(resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать фабричный resolver с 8 зависимостями от контейнера
|
||||
*/
|
||||
ResolvingContext<T> toFactory8<T1, T2, T3, T4, T5, T6, T7, T8>(
|
||||
T Function(T1, T2, T3, T4, T5, T6, T7, T8) factory) {
|
||||
Resolver<T> resolver = FactoryResolver<T>(() => factory(
|
||||
_container.resolve<T1>(),
|
||||
_container.resolve<T2>(),
|
||||
_container.resolve<T3>(),
|
||||
_container.resolve<T4>(),
|
||||
_container.resolve<T5>(),
|
||||
_container.resolve<T6>(),
|
||||
_container.resolve<T7>(),
|
||||
_container.resolve<T8>()));
|
||||
return toResolver(resolver);
|
||||
}
|
||||
|
||||
void _verify() {
|
||||
if (_resolver == null) {
|
||||
throw StateError("Can\'t resolve T without any resolvers. " +
|
||||
"Please check, may be you didn\'t do anything after bind()");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import 'package:dart_di/resolvers/resolver.dart';
|
||||
|
||||
class SingletonResolver<T> extends Resolver<T> {
|
||||
Resolver<T> _decoratedResolver;
|
||||
T? _value = null;
|
||||
|
||||
SingletonResolver(this._decoratedResolver);
|
||||
|
||||
@override
|
||||
T? resolve() {
|
||||
if (_value == null) {
|
||||
_value = _decoratedResolver.resolve();
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import 'package:dart_di/resolvers/resolver.dart';
|
||||
|
||||
/**
|
||||
* Разрешает зависимость для значения
|
||||
*/
|
||||
class ValueResolver<T> extends Resolver<T> {
|
||||
T _value;
|
||||
|
||||
ValueResolver(this._value);
|
||||
|
||||
@override
|
||||
T resolve() {
|
||||
return _value;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:dart_di/experimental/binding.dart';
|
||||
import 'package:dart_di/experimental/module.dart';
|
||||
import 'package:dart_di/binding.dart';
|
||||
import 'package:dart_di/module.dart';
|
||||
|
||||
Scope openRootScope() => Scope(null);
|
||||
|
||||
Reference in New Issue
Block a user