Permalink
Browse files

feature: ServiceProvider acts as Singleton-Factory

  • Loading branch information...
MikeMitterer committed Feb 6, 2019
1 parent 545b471 commit 2a5432a0744b5eaada71f66e34926f5bffb907ae
Showing with 38 additions and 5 deletions.
  1. +8 −3 lib/m4d_ioc.dart
  2. +30 −2 test/unit/ioc/IOCContainer_test.dart
@@ -25,6 +25,7 @@ import 'package:validate/validate.dart';
typedef Map<String, dynamic> ToJson();
typedef Map<String, Function> ToEvents();
typedef String AsString();
typedef T InstanceFactory<T>();

Container _container = Container();

@@ -137,11 +138,15 @@ class InstanceService extends Service {
InstanceService(final String name) : super(name, ServiceType.Instance);
}

/// ServiceProvider acts as a Singleton-Factory
class ServiceProvider<T> {
final T _instance;
ServiceProvider(this._instance);
static dynamic _instance = null;

InstanceFactory<T> _factory;

T get() => _instance;
ServiceProvider(this._factory);

T get() => _instance ??= _factory();
}

/// [Container] is a singleton
@@ -12,10 +12,12 @@ abstract class JsonSerializer {
}

class _TestClass extends _BaseTestClass implements JsonSerializer {
static int instanceCounter = 0;

final String firstname;
final String lastname;

_TestClass(this.firstname, this.lastname);
_TestClass(this.firstname, this.lastname) { instanceCounter++; }

@override
Map<String, dynamic> toJson() =>
@@ -24,6 +26,7 @@ class _TestClass extends _BaseTestClass implements JsonSerializer {

final TestService = Service<_TestClass>("test.unit.ioccontainer.TestService", ServiceType.Instance);
final TestProvider = Service<ServiceProvider<_TestClass>>("test.unit.ioccontainer.TestProvider", ServiceType.Provider);
final TestProvider2 = Service<ServiceProvider<_TestClass>>("test.unit.ioccontainer.TestProvider2", ServiceType.Provider);
final TestServiceForFunction = Service<Function>("test.unit.ioccontainer.Function", ServiceType.Function);
final TestServiceFirstName = Service<AsString>("test.unit.ioccontainer.FirstName", ServiceType.Function);
final TestServiceLastName = Service<AsString>("test.unit.ioccontainer.LastName", ServiceType.Function);
@@ -67,7 +70,9 @@ main() async {
final container = Container();

group('Container', () {
setUp(() {});
setUp(() {
_TestClass.instanceCounter = 0;
});
tearDown(() {
container.clear();
});
@@ -163,6 +168,29 @@ main() async {

}); // end of 'Provider I' test

test('> ServiceProvider with Factory-CTOR should produce only one instance', () {
expect(_TestClass.instanceCounter, 0);

TestProvider2.bind.to(ServiceProvider<_TestClass>(()
=> _TestClass("Gerda", "Riedmann")));

// Factory function was not called because we did not execute "get"
expect(_TestClass.instanceCounter, 0);

final tc = TestProvider2.resolve().get();
expect(tc.firstname, "Gerda");
expect(tc.lastname, "Riedmann");
expect(_TestClass.instanceCounter, 1);

[1,2,3,4,5].forEach((_) {
final tc = TestProvider2.resolve().get();
expect(tc.firstname, "Gerda");
expect(tc.lastname, "Riedmann");
expect(_TestClass.instanceCounter, 1);
});

});

test('> Service mapper', () {
TestProvider.bind.to(TestServiceProvider());

0 comments on commit 2a5432a

Please sign in to comment.