Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revise and improve cached factory handling with params #387

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions lib/get_it_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ class _ServiceFactory<T extends Object, P1, P2> {
/// returns an instance depending on the type of the registration if [async==false]
T getObject(dynamic param1, dynamic param2) {
assert(
!(factoryType != _ServiceFactoryType.alwaysNew &&
!(![_ServiceFactoryType.alwaysNew, _ServiceFactoryType.cachedFactory]
.contains(factoryType) &&
(param1 != null || param2 != null)),
'You can only pass parameters to factories!',
);
Expand Down Expand Up @@ -201,6 +202,8 @@ class _ServiceFactory<T extends Object, P1, P2> {
param2 == lastParam2) {
return weakReferenceInstance!.target!;
} else {
lastParam1 = param1 as P1?;
lastParam2 = param2 as P2?;
T newInstance;
if (creationFunctionParam != null) {
newInstance = creationFunctionParam!(param1 as P1, param2 as P2);
Expand Down Expand Up @@ -254,7 +257,8 @@ class _ServiceFactory<T extends Object, P1, P2> {
/// if [dependsOn.isNotEmpty].
Future<R> getObjectAsync<R>(dynamic param1, dynamic param2) async {
assert(
!(factoryType != _ServiceFactoryType.alwaysNew &&
!(![_ServiceFactoryType.alwaysNew, _ServiceFactoryType.cachedFactory]
.contains(factoryType) &&
(param1 != null || param2 != null)),
'You can only pass parameters to factories!',
);
Expand Down Expand Up @@ -291,6 +295,8 @@ class _ServiceFactory<T extends Object, P1, P2> {
return Future<R>.value(weakReferenceInstance!.target! as R);
} else {
if (creationFunctionParam != null) {
lastParam1 = param1 as P1?;
lastParam2 = param2 as P2?;
return asyncCreationFunctionParam!(param1 as P1, param2 as P2)
.then((value) {
weakReferenceInstance = WeakReference(value);
Expand Down
80 changes: 78 additions & 2 deletions test/get_it_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ class TestClassDisposable extends TestBaseClass with Disposable {

class TestClass2 {}

class TestClassParam {
class TestClassParam extends TestBaseClass {
final String? param1;
final int? param2;

TestClassParam({this.param1, this.param2});
TestClassParam({this.param1, this.param2}) {
constructorCounter++;
}
}

class TestClassDisposableWithDependency with Disposable {
Expand Down Expand Up @@ -216,6 +218,80 @@ void main() {
GetIt.I.reset();
});

test('register cached factory', () {
final getIt = GetIt.instance;
constructorCounter = 0;
getIt.registerCachedFactory<TestBaseClass>(() => TestClass());
final TestBaseClass instance1 = getIt<TestBaseClass>();
expect(instance1 is TestClass, true);
final instance2 = getIt.get<TestBaseClass>();
expect(getIt.isRegistered<TestBaseClass>(), true);
expect(instance1, instance2);
expect(constructorCounter, 1);
});

test('register cached factory with one param ', () {
final getIt = GetIt.instance;
constructorCounter = 0;
getIt.registerCachedFactoryParam<TestClassParam, String, void>(
(s, _) => TestClassParam(param1: s),
);
final instance1 = getIt<TestClassParam>(param1: 'abc');
final instance2 = getIt<TestClassParam>(param1: 'abc');
expect(instance1 is TestClassParam, true);
expect(instance1.param1, 'abc');
expect(instance1, instance2);
expect(constructorCounter, 1);
});

test('register cached factory with different params', () {
final getIt = GetIt.instance;
constructorCounter = 0;
getIt.registerCachedFactoryParam<TestClassParam, String, void>(
(s, _) => TestClassParam(param1: s),
);
final instance1 = getIt<TestClassParam>(param1: 'abc');
final instance2 = getIt<TestClassParam>(param1: '123');
expect(instance1 is TestClassParam, true);
expect(instance1.param1, 'abc');
expect(instance2.param1, '123');
expect(instance2 is TestClassParam, true);
expect(instance1, isNot(instance2));
expect(constructorCounter, 2);
});

test('register cached factory with two equal params', () {
final getIt = GetIt.instance;
constructorCounter = 0;
getIt.registerCachedFactoryParam<TestClassParam, String, int>(
(f, s) => TestClassParam(param1: f, param2: s),
);
final instance1 = getIt<TestClassParam>(param1: 'abc', param2: 1);
final instance2 = getIt<TestClassParam>(param1: 'abc', param2: 1);
expect(instance1 is TestClassParam, true);
expect(instance1.param1, 'abc');
expect(instance1, instance2);
expect(constructorCounter, 1);
});

test('register cached factory with one different param out of two', () {
final getIt = GetIt.instance;
constructorCounter = 0;
getIt.registerCachedFactoryParam<TestClassParam, String, int>(
(f, s) => TestClassParam(param1: f, param2: s),
);
final instance1 = getIt<TestClassParam>(param1: 'abc', param2: 1);
final instance2 = getIt<TestClassParam>(param1: 'abc', param2: 2);
expect(instance1 is TestClassParam, true);
expect(instance1.param1, 'abc');
expect(instance1.param2, 1);
expect(instance2.param1, 'abc');
expect(instance2.param2, 2);
expect(instance2 is TestClassParam, true);
expect(instance1, isNot(instance2));
expect(constructorCounter, 2);
});

test('register constant', () {
final getIt = GetIt.instance;
constructorCounter = 0;
Expand Down
Loading