diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 42be89c..01b927d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -21,18 +21,18 @@ jobs:
- name: Install .NET Core
uses: actions/setup-dotnet@v3
with:
- dotnet-version: 6.0.x
+ dotnet-version: 8.0.x
- name: Install Codecov
run: choco install codecov -y
- name: Build and test ServicePool
- run: dotnet test $env:Solution_Name --configuration=$env:Configuration --collect:"XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover
+ run: dotnet test $env:Solution_Name --configuration=$env:Configuration --collect:"XPlat Code Coverage" --results-directory .\Build\tests -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover
- name: Upload code coverage report
- run: codecov -f "$((ls .\src\ServicePool.Tests\TestResults -Directory)[0].Fullname)\coverage.opencover.xml"
+ run: foreach ($j in (ls .\Build\tests\ -Directory)) { codecov -f "$($j.FullName)\coverage.opencover.xml" }
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Create NuGet Packages
- run: dotnet pack $env:Solution_Name --configuration=$env:Configuration --version-suffix=$env:GITHUB_SHA --include-source -p:RepositoryBranch=${{ github.ref }} -p:ContinuousIntegrationBuild=true
+ run: dotnet pack $env:Solution_Name --configuration=$env:Configuration --version-suffix=$env:GITHUB_SHA --include-source -p:RepositoryBranch=${{ github.ref }} -p:RepositoryCommit=${{ github.sha }} -p:ContinuousIntegrationBuild=true
- uses: actions/upload-artifact@v3
with:
name: ServicePool-nuget-packages
- path: Build/Bin/**/*.nupkg
+ path: Build/Bin/**/*.nupkg
\ No newline at end of file
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index cbe00a7..ff6dcfb 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -15,16 +15,10 @@ jobs:
- name: Install .NET Core
uses: actions/setup-dotnet@v3
with:
- dotnet-version: 6.0.x
- - name: Get tag name
- uses: olegtarasov/get-tag@v2.1.2
+ dotnet-version: 8.0.x
- name: Create NuGet Packages
- run: dotnet pack $env:Solution_Name --configuration=$env:Configuration -p:Version=$env:GIT_TAG_NAME -p:RepositoryBranch=${{ github.ref }} -p:ContinuousIntegrationBuild=true
+ run: dotnet pack $env:Solution_Name --configuration=${{ env.Configuration }} -p:Version=${{ github.ref_name }} -p:RepositoryBranch=${{ github.ref }} -p:RepositoryCommit=${{ github.sha }} -p:ContinuousIntegrationBuild=true
- name: Push packages to GitHub
- run: dotnet nuget push "Build/**/*.nupkg" -k $env:GhToken --skip-duplicate --source "https://nuget.pkg.github.com/TheXDS/"
- env:
- GhToken: ${{ secrets.GITHUB_TOKEN }}
+ run: dotnet nuget push "Build/**/*.nupkg" -k ${{ secrets.GITHUB_TOKEN }} --skip-duplicate --source "https://nuget.pkg.github.com/TheXDS/"
- name: Push packages to NuGet
- run: dotnet nuget push "Build/**/*.nupkg" -k $env:NgToken --skip-duplicate --source "https://api.nuget.org/v3/index.json"
- env:
- NgToken: ${{ secrets.NUGET_TOKEN }}
+ run: dotnet nuget push "Build/**/*.nupkg" -k ${{ secrets.NUGET_TOKEN }} --skip-duplicate --source "https://api.nuget.org/v3/index.json"
\ No newline at end of file
diff --git a/BuildTargets/CompileOptions.targets b/BuildTargets/CompileOptions.targets
index 2d8034d..fb53b09 100644
--- a/BuildTargets/CompileOptions.targets
+++ b/BuildTargets/CompileOptions.targets
@@ -19,6 +19,6 @@
false
-
+
\ No newline at end of file
diff --git a/README.md b/README.md
index a1c7f19..6a5ab32 100644
--- a/README.md
+++ b/README.md
@@ -58,9 +58,22 @@ The resulting binaries will be in the `./Build/bin` directory.
```sh
dotnet test ./src/ServicePool.sln
```
+#### Coverage reports
+It is possible to generate a coverage report locally.For that, it is necessary to install [`ReportGenerator`](https://github.com/danielpalme/ReportGenerator), which will read the test results after execution, and will generate a web page with the coverage results.
+
+To install `ReportGenerator` execute:
+```sh
+dotnet tool install -g dotnet-reportgenerator-globaltool
+```
+After installing `ReportGenerator`, it will be possible to execute the following command:
+```sh
+dotnet test ./src/ServicePool.sln --collect:"XPlat Code Coverage" --results-directory:./Build/Tests ; reportgenerator -reports:./Build/Tests/*/coverage.cobertura.xml -targetdir:./Build/Coverage/
+```
+The coverage reports will be stored in `./Build/Coverage`
## Contribute
-If you think that ServicePool is useful, consider making a donation via
-[PayPal](https://paypal.me/thexds), or contact me directly.
+[](https://www.buymeacoffee.com/xdsxpsivx)
+
+If `ServicePool` is useful to you, or if you're interested in donating to sponsor the project, feel free to to a donation via [PayPal](https://paypal.me/thexds), [BuyMeACoffee](https://www.buymeacoffee.com/xdsxpsivx) or just contact me directly.
-Sadly, I cannot offer any other donation methods, as my country (Honduras) is not supported on any platform. Not even PayPal supports donations per-se to people in Honduras, but at least I have an account there.
+Sadly, I cannot offer other means of sending donations as of right now due to my country (Honduras) not being supported by almost any platform.
diff --git a/src/ServicePool.Tests/AssemblyListDiscoveryEngineTests.cs b/src/ServicePool.Tests/AssemblyListDiscoveryEngineTests.cs
index fa6dba9..f255b73 100644
--- a/src/ServicePool.Tests/AssemblyListDiscoveryEngineTests.cs
+++ b/src/ServicePool.Tests/AssemblyListDiscoveryEngineTests.cs
@@ -44,7 +44,7 @@ public void Engine_supports_add()
{
a
};
- Assert.Contains(a, e);
+ Assert.That(e, Contains.Item(a));
}
[Test]
@@ -53,7 +53,7 @@ public void Engine_supports_insert()
var a = Assembly.GetExecutingAssembly();
var e = new AssemblyListDiscoveryEngine();
e.Insert(0, a);
- Assert.Contains(a, e);
+ Assert.That(e, Contains.Item(a));
}
[Test]
@@ -63,8 +63,8 @@ public void Engine_supports_set()
var b = typeof(object).Assembly;
var e = new AssemblyListDiscoveryEngine { a };
e[0] = b;
- Assert.False(e.Contains(a));
- Assert.Contains(b, e);
+ Assert.That(e, Does.Not.Contain(a));
+ Assert.That(e, Contains.Item(b));
}
[Test]
diff --git a/src/ServicePool.Tests/CommonExtensionsTests.cs b/src/ServicePool.Tests/CommonExtensionsTests.cs
index 34b4afa..974a640 100644
--- a/src/ServicePool.Tests/CommonExtensionsTests.cs
+++ b/src/ServicePool.Tests/CommonExtensionsTests.cs
@@ -34,32 +34,32 @@
namespace TheXDS.ServicePool.Tests;
-public class CommonExtensionsTests
+public abstract class CommonExtensionsTests where T : PoolBase, new()
{
[Test]
public void RegisterInto_registers_singleton()
{
- var pool = new ServicePool();
+ var pool = new T();
var x = new Random().RegisterInto(pool);
- Assert.IsInstanceOf(x);
- Assert.AreSame(x, pool.Resolve());
+ Assert.That(x, Is.InstanceOf());
+ Assert.That(pool.Resolve(), Is.SameAs(x));
}
[Test]
public void RegisterIntoIf_registers_if_true()
{
- var pool = new ServicePool();
+ var pool = new Pool();
var x = new Random().RegisterIntoIf(pool, true);
- Assert.IsInstanceOf(x);
- Assert.AreSame(x, pool.Resolve());
+ Assert.That(x, Is.InstanceOf());
+ Assert.That(pool.Resolve(), Is.SameAs(x));
}
[Test]
- public void RegisterIntoIf_returns_null_if_false()
+ public void RegisterIntoIf_returns_object_if_false()
{
- var pool = new ServicePool();
+ var pool = new FlexPool();
var x = new Random().RegisterIntoIf(pool, false);
- Assert.IsNull(x);
- Assert.IsNull(pool.Resolve());
+ Assert.That(x, Is.InstanceOf());
+ Assert.That(pool.Resolve(), Is.Null);
}
}
diff --git a/src/ServicePool.Tests/DefaultDiscoveryEngineTests.cs b/src/ServicePool.Tests/DefaultDiscoveryEngineTests.cs
new file mode 100644
index 0000000..abad2fc
--- /dev/null
+++ b/src/ServicePool.Tests/DefaultDiscoveryEngineTests.cs
@@ -0,0 +1,47 @@
+// AssemblyListDiscoveryEngineTests.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2023 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+
+using NUnit.Framework;
+using System;
+using System.Collections;
+using System.Linq;
+
+namespace TheXDS.ServicePool.Tests;
+
+public class DefaultDiscoveryEngineTests
+{
+ [Test]
+ public void Engine_resolves_base_type()
+ {
+ var engine = new DefaultDiscoveryEngine();
+ var types = engine.Discover(typeof(Exception)).ToArray();
+ Assert.That(types.Length, Is.GreaterThan(50));
+ }
+}
diff --git a/src/ServicePool.Tests/FlexPoolExtensionsTests.cs b/src/ServicePool.Tests/FlexPoolExtensionsTests.cs
new file mode 100644
index 0000000..e23811e
--- /dev/null
+++ b/src/ServicePool.Tests/FlexPoolExtensionsTests.cs
@@ -0,0 +1,33 @@
+// FlexPoolExtensionsTests.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+
+namespace TheXDS.ServicePool.Tests;
+
+public class FlexPoolExtensionsTests : CommonExtensionsTests { }
diff --git a/src/ServicePool.Tests/FlexPoolTests.cs b/src/ServicePool.Tests/FlexPoolTests.cs
new file mode 100644
index 0000000..829953c
--- /dev/null
+++ b/src/ServicePool.Tests/FlexPoolTests.cs
@@ -0,0 +1,121 @@
+// FlexPoolTests.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using TheXDS.ServicePool.Extensions;
+using TheXDS.ServicePool.TestTypes;
+
+namespace TheXDS.ServicePool.Tests;
+
+public class FlexPoolTests : PoolBaseTests
+{
+ [Test]
+ public void Resolve_resolves_for_interfaces()
+ {
+ FlexPool? pool = new();
+ pool.Register();
+ Assert.That(pool.Resolve(), Is.Not.Null);
+ }
+
+ [Test]
+ public void Resolve_resolves_for_base_class()
+ {
+ FlexPool? pool = new();
+ pool.Register();
+ Assert.That(pool.Resolve(), Is.Not.Null);
+ }
+
+ [Test]
+ public void Discover_searches_for_service()
+ {
+ FlexPool? pool = new();
+ Assert.That(pool.Discover(), Is.InstanceOf());
+ Assert.That(pool.Count, Is.EqualTo(1));
+ }
+
+ [Test]
+ public void Discover_returns_from_active_services()
+ {
+ FlexPool? pool = new();
+ pool.Register();
+ var r = pool.Resolve();
+ Assert.That(pool.Discover(), Is.SameAs(r));
+ }
+
+ [Test]
+ public void ResolveAll_returns_collection()
+ {
+ FlexPool pool = new();
+ pool.RegisterNow(new List());
+ pool.RegisterNow(new Collection());
+ pool.RegisterNow(Array.Empty());
+ Assert.That(pool.ResolveAll>().Count(), Is.EqualTo(3));
+ }
+
+ [Test]
+ public void DiscoverAll_enumerates_all_types_that_implement_base_type()
+ {
+ FlexPool pool = new();
+ Assert.That(pool.DiscoverAll().ToArray().Length, Is.EqualTo(3));
+ }
+
+ [Test]
+ public void DiscoverAll_skips_existing_services()
+ {
+ FlexPool pool = new();
+ pool.RegisterNow();
+ var t1 = pool.Resolve();
+ ITest[] c = pool.DiscoverAll().ToArray();
+ Assert.That(c.Length, Is.EqualTo(3));
+ Assert.That(c[0], Is.SameAs(t1));
+ Assert.That(c[1], Is.InstanceOf());
+ Assert.That(c[2], Is.InstanceOf());
+ }
+
+ [Test]
+ public void DiscoverAll_allows_specifying_engine()
+ {
+ FlexPool pool = new();
+ ITest[] c = pool.DiscoverAll(new DefaultDiscoveryEngine()).ToArray();
+ Assert.That(c.Length, Is.EqualTo(3));
+ }
+
+ [Test]
+ public void Discover_allows_specifying_engine()
+ {
+ FlexPool pool = new();
+ var c = pool.Discover(new DefaultDiscoveryEngine());
+ Assert.That(c, Is.Not.Null);
+ }
+}
diff --git a/src/ServicePool.Tests/PoolBaseTests.cs b/src/ServicePool.Tests/PoolBaseTests.cs
new file mode 100644
index 0000000..13f56bc
--- /dev/null
+++ b/src/ServicePool.Tests/PoolBaseTests.cs
@@ -0,0 +1,235 @@
+// TTests.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+#pragma warning disable IDE0290
+#pragma warning disable IDE0060
+
+using NUnit.Framework;
+using System;
+using System.Collections;
+using System.Linq;
+using System.Reflection;
+using TheXDS.ServicePool.TestTypes;
+
+namespace TheXDS.ServicePool.Tests;
+
+public abstract class PoolBaseTests where T : PoolBase, new()
+{
+ [Test]
+ public void Count_gets_total_service_count()
+ {
+ T pool = new();
+ Assert.That(pool.Count, Is.Zero);
+
+ pool.RegisterNow();
+ Assert.That(pool.Count, Is.EqualTo(1));
+
+ pool.RegisterNow();
+ Assert.That(pool.Count, Is.EqualTo(2));
+
+ pool.Register();
+ Assert.That(pool.Count, Is.EqualTo(3));
+ }
+
+ [Test]
+ public void Pool_registers_and_resolves_cached_services()
+ {
+ T pool = new();
+ pool.RegisterNow();
+ Assert.That(pool.Resolve(), Is.InstanceOf());
+ }
+
+ [Test]
+ public void Pool_resolves_persistent_services()
+ {
+ T pool = new();
+ pool.Register(true);
+ Random? r1 = pool.Resolve();
+ Random? r2 = pool.Resolve();
+
+ Assert.That(r1, Is.InstanceOf());
+ Assert.That(r2, Is.InstanceOf());
+ Assert.That(r1, Is.SameAs(r2));
+ }
+
+ [Test]
+ public void InitNow_initializes_services()
+ {
+ T pool = new();
+ pool.Register(true);
+ pool.InitNow();
+ Assert.That(pool.Count, Is.Not.Zero);
+ }
+
+ [Test]
+ public void Pool_resolves_non_persistent_services()
+ {
+ T pool = new();
+ pool.Register(false);
+ Random? r1 = pool.Resolve();
+ Random? r2 = pool.Resolve();
+
+ Assert.That(r1, Is.InstanceOf());
+ Assert.That(r2, Is.InstanceOf());
+ Assert.That(r1, Is.Not.SameAs(r2));
+ }
+
+ [Test]
+ public void Resolve_returns_null_if_not_registered()
+ {
+ T pool = new();
+ Assert.That(pool.Resolve(), Is.Null);
+ }
+
+ [Test]
+ public void Pool_supports_removal_of_lazy_services()
+ {
+ T pool = new();
+ pool.Register();
+
+ Assert.That(pool.Remove(), Is.True);
+ Assert.That(pool.Count, Is.Zero);
+ }
+
+ [Test]
+ public void Pool_supports_removal_of_eager_services()
+ {
+ T pool = new();
+ pool.RegisterNow();
+
+ Assert.That(pool.Remove(), Is.True);
+ Assert.That(pool.Count, Is.Zero);
+ }
+
+ [Test]
+ public void Remove_returns_false_if_service_is_not_registered()
+ {
+ T pool = new();
+ Assert.That(pool.Remove(), Is.False);
+ Assert.That(pool.Count, Is.Zero);
+ }
+
+ [Test]
+ public void Consume_removes_service()
+ {
+ T pool = new();
+ pool.RegisterNow();
+ Assert.That(pool.Consume(), Is.InstanceOf());
+ Assert.That(pool.Count, Is.Zero);
+ Assert.That(pool.Consume(), Is.Null);
+ }
+
+ [Test]
+ public void Consume_returns_null_if_no_service_is_available()
+ {
+ T pool = new();
+ Assert.That(pool.Consume(), Is.Null);
+ }
+
+ [Test]
+ public void Consume_returns_null_if_service_was_consumed()
+ {
+ T pool = new();
+ pool.RegisterNow();
+ pool.Consume();
+
+ Assert.That(pool.Consume(), Is.Null);
+ }
+
+ [Test]
+ public void Enumerator_includes_lazy_and_eager_items()
+ {
+ T pool = new();
+ pool.RegisterNow();
+ pool.Register();
+
+ IEnumerator e = pool.GetEnumerator();
+ Assert.That(e, Is.InstanceOf());
+ int c = 0;
+ while (e.MoveNext())
+ {
+ Assert.That(e.Current, Is.InstanceOf());
+ c++;
+ }
+ Assert.That(c, Is.EqualTo(2));
+ }
+
+ [Test]
+ public void ServicePool_throws_error_on_invalid_registrations()
+ {
+ T pool = new();
+ Assert.Catch(pool.RegisterNow);
+ Assert.Catch(pool.RegisterNow);
+ }
+
+ [Test]
+ public void ServicePool_errors_have_messages()
+ {
+ T pool = new();
+ var ex = Assert.Catch(pool.RegisterNow);
+ Assert.That(ex, Is.Not.Null);
+ Assert.That(ex!.Message, Is.Not.Empty);
+ }
+
+ [TestCase("en_US")]
+ [TestCase("es_MX")]
+ public void ServicePool_strings_have_localized_messages(string locale)
+ {
+ Resources.Strings.Errors.Culture = new(locale);
+ foreach (var prop in typeof(Resources.Strings.Errors)
+ .GetProperties(BindingFlags.Static | BindingFlags.Public)
+ .Where(p => p.PropertyType == typeof(string))
+ .Select(p => p.GetValue(null)).Cast())
+ {
+ Assert.That(string.IsNullOrWhiteSpace(prop), Is.False);
+ }
+ }
+
+ [Test]
+ public void ServicePool_throws_error_on_uninstantiable_class()
+ {
+ T pool = new();
+ pool.Register(() => 3);
+ Assert.Catch(pool.RegisterNow);
+ }
+
+ [Test]
+ public void ServicePool_injects_dependencies()
+ {
+ T pool = new();
+ pool.Register();
+ pool.Register();
+ pool.Register();
+
+ var t4 = pool.Resolve()!;
+ Assert.That(t4, Is.InstanceOf());
+ Assert.That(t4.Random, Is.InstanceOf());
+ Assert.That(t4.Test1, Is.InstanceOf());
+ }
+}
diff --git a/src/ServicePool.Tests/PoolExtensionsTests.cs b/src/ServicePool.Tests/PoolExtensionsTests.cs
new file mode 100644
index 0000000..585fa8d
--- /dev/null
+++ b/src/ServicePool.Tests/PoolExtensionsTests.cs
@@ -0,0 +1,33 @@
+// PoolExtensionsTests.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+
+namespace TheXDS.ServicePool.Tests;
+
+public class PoolExtensionsTests : CommonExtensionsTests { }
diff --git a/src/ServicePool.Tests/PoolTests.cs b/src/ServicePool.Tests/PoolTests.cs
new file mode 100644
index 0000000..5c85224
--- /dev/null
+++ b/src/ServicePool.Tests/PoolTests.cs
@@ -0,0 +1,80 @@
+// FlexPoolTests.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+
+using NUnit.Framework;
+using System;
+using TheXDS.ServicePool.TestTypes;
+
+namespace TheXDS.ServicePool.Tests;
+
+public class PoolTests : PoolBaseTests
+{
+ [Test]
+ public void Resolve_resolves_for_interfaces()
+ {
+ Pool? pool = new();
+ pool.Register();
+ Assert.That(pool.Resolve(), Is.Not.Null);
+ }
+
+ [Test]
+ public void Resolve_resolves_for_base_class()
+ {
+ Pool? pool = new();
+ pool.Register();
+ Assert.That(pool.Resolve(), Is.Not.Null);
+ }
+
+ [TestCase(typeof(ITest))]
+ [TestCase(typeof(Test1))]
+ [TestCase(typeof(Test3))]
+ public void Resolve_resolves_for_various_types(Type resolvableType)
+ {
+ Pool? pool = new();
+ pool.Register([typeof(ITest), typeof(Test1), typeof(Test3)]);
+ Assert.That(pool.Resolve(resolvableType), Is.Not.Null);
+ }
+
+ [Test]
+ public void Resolve_returns_null_if_not_explicitly_registered_for_interface()
+ {
+ Pool? pool = new();
+ pool.Register();
+ Assert.That(pool.Resolve(), Is.Null);
+ }
+
+ [Test]
+ public void Resolve_returns_null_if_not_explicitly_registered_for_own_type()
+ {
+ Pool? pool = new();
+ pool.Register();
+ Assert.That(pool.Resolve(), Is.Null);
+ }
+}
diff --git a/src/ServicePool.Tests/ServicePool.Tests.csproj b/src/ServicePool.Tests/ServicePool.Tests.csproj
index 725627a..8cd3ecd 100644
--- a/src/ServicePool.Tests/ServicePool.Tests.csproj
+++ b/src/ServicePool.Tests/ServicePool.Tests.csproj
@@ -1,17 +1,17 @@
-
+
- net6.0
+ net8.0
enable
false
-
-
-
-
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -21,8 +21,4 @@
-
-
-
-
diff --git a/src/ServicePool.Tests/ServicePoolTests.cs b/src/ServicePool.Tests/ServicePoolTests.cs
deleted file mode 100644
index 4edc578..0000000
--- a/src/ServicePool.Tests/ServicePoolTests.cs
+++ /dev/null
@@ -1,403 +0,0 @@
-// ServicePoolTests.cs
-//
-// This file is part of ServicePool
-//
-// Author(s):
-// César Andrés Morgan
-//
-// Released under the MIT License (MIT)
-// Copyright © 2011 - 2022 César Andrés Morgan
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy of
-// this software and associated documentation files (the “Software”), to deal in
-// the Software without restriction, including without limitation the rights to
-// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-// of the Software, and to permit persons to whom the Software is furnished to do
-// so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-#pragma warning disable CS1591
-
-using NUnit.Framework;
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Reflection;
-
-namespace TheXDS.ServicePool.Tests;
-
-public class ServicePoolTests
-{
- [Test]
- public void Registration_api_is_fluent()
- {
- ServicePool? pool = new();
- Assert.AreSame(pool, pool.Register());
- Assert.AreSame(pool, pool.Register(DummyFactory));
- Assert.AreSame(pool, pool.InitNow());
- Assert.AreSame(pool, pool.RegisterNow());
- Assert.AreSame(pool, pool.RegisterNow(new object()));
- Assert.AreSame(pool, pool.RegisterIf(false));
- Assert.AreSame(pool, pool.RegisterIf(false, DummyFactory));
- Assert.AreSame(pool, pool.RegisterNowIf(false));
- Assert.AreSame(pool, pool.RegisterNowIf(false, new object()));
- }
-
- [Test]
- public void ActiveCount_gets_correct_count()
- {
- ServicePool? pool = new();
- Assert.Zero(pool.ActiveCount);
-
- pool.RegisterNow();
- Assert.AreEqual(1, pool.ActiveCount);
-
- pool.RegisterNow();
- Assert.AreEqual(2, pool.ActiveCount);
-
- pool.Register();
- Assert.AreEqual(2, pool.ActiveCount);
- }
-
- [Test]
- public void Count_gets_total_service_count()
- {
- ServicePool? pool = new();
- Assert.Zero(pool.Count);
-
- pool.RegisterNow();
- Assert.AreEqual(1, pool.Count);
-
- pool.RegisterNow();
- Assert.AreEqual(2, pool.Count);
-
- pool.Register();
- Assert.AreEqual(3, pool.Count);
- }
-
- [Test]
- public void Pool_registers_and_resolves_cached_services()
- {
- ServicePool? pool = new ServicePool().RegisterNow();
- Assert.IsInstanceOf(pool.Resolve());
- }
-
- [Test]
- public void Pool_resolves_persistent_services()
- {
- ServicePool? pool = new ServicePool().Register(true);
- Random? r1 = pool.Resolve();
- Random? r2 = pool.Resolve();
-
- Assert.IsInstanceOf(r1);
- Assert.IsInstanceOf(r2);
- Assert.AreSame(r1, r2);
- }
-
- [Test]
- public void Pool_resolves_non_persistent_services()
- {
- ServicePool? pool = new ServicePool().Register(false);
- Random? r1 = pool.Resolve();
- Random? r2 = pool.Resolve();
-
- Assert.IsInstanceOf(r1);
- Assert.IsInstanceOf(r2);
- Assert.AreNotSame(r1, r2);
- }
-
- [Test]
- public void Resolve_returns_null_if_not_registered()
- {
- ServicePool? pool = new();
- Assert.IsNull(pool.Resolve());
- }
-
- [Test]
- public void Resolve_resolves_for_interfaces()
- {
- ServicePool? pool = new();
- pool.Register();
- Assert.IsNotNull(pool.Resolve());
- }
-
- [Test]
- public void Resolve_resolves_for_base_class()
- {
- ServicePool? pool = new();
- pool.Register();
- Assert.IsNotNull(pool.Resolve());
- }
-
- [Test]
- public void Pool_inits_lazy_services_on_InitNow()
- {
- ServicePool? pool = new ServicePool().Register();
- Assert.Zero(pool.ActiveCount);
- pool.InitNow();
- Assert.AreEqual(1, pool.ActiveCount);
- }
-
- [Test]
- public void InitNow_skips_non_persistent_services()
- {
- ServicePool? pool = new ServicePool().Register(false);
- Assert.Zero(pool.ActiveCount);
- pool.InitNow();
- Assert.Zero(pool.ActiveCount);
- }
-
- [Test]
- public void RegisterIf_skips_if_false()
- {
- ServicePool? pool = new ServicePool().RegisterIf(false);
- Assert.Zero(pool.Count);
- pool.RegisterIf(true);
- Assert.AreEqual(1, pool.Count);
- pool.RegisterIf(false, DummyFactory);
- Assert.AreEqual(1, pool.Count);
- pool.RegisterIf(true, DummyFactory);
- Assert.AreEqual(2, pool.Count);
- }
-
- [Test]
- public void RegisterNowIf_skips_if_false()
- {
- ServicePool? pool = new ServicePool().RegisterNowIf(false);
- Assert.Zero(pool.Count);
- pool.RegisterNowIf(true);
- Assert.AreEqual(1, pool.Count);
- pool.RegisterNowIf(false, new Exception());
- Assert.AreEqual(1, pool.Count);
- pool.RegisterNowIf(true, new Exception());
- Assert.AreEqual(2, pool.Count);
- }
-
- [Test]
- public void Discover_searches_for_service()
- {
- ServicePool? pool = new();
- Assert.IsInstanceOf(pool.Discover());
- Assert.AreEqual(1, pool.Count);
- }
-
- [Test]
- public void Discover_returns_from_active_services()
- {
- ServicePool? pool = new();
- pool.Register();
- var r = pool.Resolve();
- Assert.AreSame(r, pool.Discover());
- }
-
- [Test]
- public void ResolveAll_returns_collection()
- {
- ServicePool pool = new();
- pool.RegisterNow(new List());
- pool.RegisterNow(new Collection());
- pool.RegisterNow(Array.Empty());
- Assert.AreEqual(3, pool.ResolveAll>().Count());
- }
-
- [Test]
- public void DiscoverAll_enumerates_all_types_that_implement_base_type()
- {
- ServicePool pool = new();
- Assert.AreEqual(3, pool.DiscoverAll().ToArray().Length);
- }
-
- [Test]
- public void DiscoverAll_skips_existing_services()
- {
- ServicePool pool = new();
- pool.RegisterNow();
- var t1 = pool.Resolve();
- ITest[] c = pool.DiscoverAll().ToArray();
- Assert.AreEqual(3, c.Length);
- Assert.AreSame(t1, c[0]);
- Assert.IsInstanceOf(c[1]);
- Assert.IsInstanceOf(c[2]);
- }
-
- [Test]
- public void Pool_supports_removal()
- {
- ServicePool pool = new();
- pool.RegisterNow();
- pool.Register();
- Assert.IsTrue(pool.Remove());
- Assert.AreEqual(1, pool.Count);
- Assert.IsFalse(pool.Remove());
- Assert.IsTrue(pool.Remove());
- Assert.Zero(pool.Count);
- Assert.IsFalse(pool.Remove());
- }
-
- [Test]
- public void Consume_removes_service()
- {
- ServicePool pool = new();
- pool.RegisterNow();
- Assert.IsInstanceOf(pool.Consume());
- Assert.Zero(pool.Count);
- Assert.Null(pool.Consume());
- pool.Register();
- Assert.IsInstanceOf(pool.Consume());
- Assert.Zero(pool.Count);
- Assert.Null(pool.Consume());
- }
-
- [Test]
- public void Enumerator_includes_lazy_and_eager_items()
- {
- ServicePool pool = new();
- pool.RegisterNow().Register();
-
- IEnumerator e = pool.GetEnumerator();
- Assert.IsInstanceOf(e);
- int c = 0;
- while (e.MoveNext())
- {
- Assert.IsInstanceOf(e.Current);
- c++;
- }
- Assert.AreEqual(2, c);
- }
-
- [Test]
- public void Common_ServicePool_exists()
- {
- Assert.IsAssignableFrom(ServicePool.CommonPool);
- ServicePool pool = ServicePool.CommonPool;
- Assert.AreSame(pool, ServicePool.CommonPool);
- }
-
- [Test]
- public void ServicePool_throws_error_on_invalid_registrations()
- {
- ServicePool pool = new();
- Assert.Catch(() => pool.RegisterNow());
- Assert.Catch(() => pool.RegisterNow());
- }
-
- [Test]
- public void ServicePool_errors_have_messages()
- {
- ServicePool pool = new();
- var ex = Assert.Catch(() => pool.RegisterNow());
- Assert.IsNotNull(ex);
- Assert.IsNotEmpty(ex!.Message);
- }
-
- [TestCase("en_US")]
- [TestCase("es_MX")]
- public void ServicePool_strings_have_localized_messages(string locale)
- {
- Resources.Strings.Errors.Culture = new(locale);
- foreach (var prop in typeof(Resources.Strings.Errors)
- .GetProperties(BindingFlags.Static | BindingFlags.Public)
- .Where(p => p.PropertyType == typeof(string))
- .Select(p => p.GetValue(null)).Cast())
- {
- Assert.IsFalse(string.IsNullOrWhiteSpace(prop));
- }
- }
-
- [Test]
- public void ServicePool_throws_error_on_uninstantiable_class()
- {
- ServicePool pool = new();
- pool.Register(() => 3);
- Assert.Catch(() => pool.RegisterNow());
- }
-
- [Test]
- public void ServicePool_injects_dependencies()
- {
- ServicePool pool = new ServicePool()
- .Register()
- .Register()
- .Register();
-
- var t4 = pool.Resolve()!;
- Assert.IsInstanceOf(t4);
- Assert.IsInstanceOf(t4.Random);
- Assert.IsInstanceOf(t4.Test1);
- }
-
- private interface ITest
- {
- [ExcludeFromCodeCoverage]
- void Test();
- }
-
- [ExcludeFromCodeCoverage]
- private static object DummyFactory()
- {
- return new object();
- }
-
- [ExcludeFromCodeCoverage]
- private abstract class AbstractTest : ITest
- {
- public abstract void Test();
- }
-
- [ExcludeFromCodeCoverage]
- private class UninstantiableTest
- {
- public UninstantiableTest(int x, Exception y, Guid z, IEnumerator a)
- {
- }
- }
-
- [ExcludeFromCodeCoverage]
- private class Test1 : ITest
- {
- public void Test()
- {
- Assert.Pass();
- }
- }
-
- [ExcludeFromCodeCoverage]
- private class Test2 : ITest
- {
- void ITest.Test()
- {
- Assert.Pass();
- }
- }
-
- [ExcludeFromCodeCoverage]
- private class Test3 : Test1
- {
- }
-
- [ExcludeFromCodeCoverage]
- private class Test4
- {
- public Test4(Random random, Test1 test1)
- {
- Random = random;
- Test1 = test1;
- }
-
- public Random Random { get; }
- public Test1 Test1 { get; }
- }
-}
diff --git a/src/ServicePool.Tests/SugarExtensionsTests.cs b/src/ServicePool.Tests/SugarExtensionsTests.cs
new file mode 100644
index 0000000..7dfce60
--- /dev/null
+++ b/src/ServicePool.Tests/SugarExtensionsTests.cs
@@ -0,0 +1,109 @@
+// SugarExtensionsTests.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+
+using NUnit.Framework;
+using System;
+using System.Diagnostics.CodeAnalysis;
+using TheXDS.ServicePool.Extensions;
+
+namespace TheXDS.ServicePool.Tests;
+
+public class SugarExtensionsTests
+{
+ [Test]
+ public void RegisterIf_T_skips_if_false()
+ {
+ FlexPool? pool = new();
+ pool.RegisterIf(false);
+ Assert.That(pool.Count, Is.Zero);
+ }
+
+ [Test]
+ public void RegisterIf_T_registers_if_true()
+ {
+ FlexPool? pool = new();
+ pool.RegisterIf(true);
+ Assert.That(pool.Count, Is.EqualTo(1));
+ }
+
+ [Test]
+ public void RegisterIf_with_factory_skips_if_false()
+ {
+ FlexPool? pool = new();
+ pool.RegisterIf(false, DummyFactory);
+ Assert.That(pool.Count, Is.Zero);
+ }
+
+ [Test]
+ public void RegisterIf_with_factory_registers_if_true()
+ {
+ FlexPool? pool = new();
+ pool.RegisterIf(true, DummyFactory);
+ Assert.That(pool.Count, Is.EqualTo(1));
+ }
+
+ [Test]
+ public void RegisterNowIf_T_skips_if_false()
+ {
+ FlexPool? pool = new();
+ pool.RegisterNowIf(false);
+ Assert.That(pool.Count, Is.Zero);
+ }
+
+ [Test]
+ public void RegisterNowIf_T_registers_if_true()
+ {
+ FlexPool? pool = new();
+ pool.RegisterNowIf(true);
+ Assert.That(pool.Count, Is.EqualTo(1));
+ }
+
+ [Test]
+ public void RegisterNowIf_with_singleton_skips_if_false()
+ {
+ FlexPool? pool = new();
+ pool.RegisterNowIf(false, new Exception());
+ Assert.That(pool.Count, Is.Zero);
+ }
+
+ [Test]
+ public void RegisterNowIf_with_singleton_registers_if_true()
+ {
+ FlexPool? pool = new();
+ pool.RegisterNowIf(true, new Exception());
+ Assert.That(pool.Count, Is.EqualTo(1));
+ }
+
+ [ExcludeFromCodeCoverage]
+ private static object DummyFactory()
+ {
+ return new object();
+ }
+}
diff --git a/src/ServicePool.Tests/TestTypes/AbstractTest.cs b/src/ServicePool.Tests/TestTypes/AbstractTest.cs
new file mode 100644
index 0000000..c2790ca
--- /dev/null
+++ b/src/ServicePool.Tests/TestTypes/AbstractTest.cs
@@ -0,0 +1,39 @@
+// AbstractTest.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+
+using System.Diagnostics.CodeAnalysis;
+
+namespace TheXDS.ServicePool.TestTypes;
+
+[ExcludeFromCodeCoverage]
+public abstract class AbstractTest : ITest
+{
+ public abstract void Test();
+}
diff --git a/src/ServicePool.Tests/TestTypes/ITest.cs b/src/ServicePool.Tests/TestTypes/ITest.cs
new file mode 100644
index 0000000..88e382b
--- /dev/null
+++ b/src/ServicePool.Tests/TestTypes/ITest.cs
@@ -0,0 +1,41 @@
+// ITest.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+#pragma warning disable IDE0290
+#pragma warning disable IDE0060
+
+using System.Diagnostics.CodeAnalysis;
+
+namespace TheXDS.ServicePool.TestTypes;
+
+public interface ITest
+{
+ [ExcludeFromCodeCoverage]
+ void Test();
+}
diff --git a/src/ServicePool.Tests/TestTypes/Test1.cs b/src/ServicePool.Tests/TestTypes/Test1.cs
new file mode 100644
index 0000000..a01d99e
--- /dev/null
+++ b/src/ServicePool.Tests/TestTypes/Test1.cs
@@ -0,0 +1,43 @@
+// Test1.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+
+using NUnit.Framework;
+using System.Diagnostics.CodeAnalysis;
+
+namespace TheXDS.ServicePool.TestTypes;
+
+[ExcludeFromCodeCoverage]
+public class Test1 : ITest
+{
+ public void Test()
+ {
+ Assert.Pass();
+ }
+}
diff --git a/src/ServicePool.Tests/TestTypes/Test2.cs b/src/ServicePool.Tests/TestTypes/Test2.cs
new file mode 100644
index 0000000..3ba21ed
--- /dev/null
+++ b/src/ServicePool.Tests/TestTypes/Test2.cs
@@ -0,0 +1,43 @@
+// Test2.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+
+using NUnit.Framework;
+using System.Diagnostics.CodeAnalysis;
+
+namespace TheXDS.ServicePool.TestTypes;
+
+[ExcludeFromCodeCoverage]
+public class Test2 : ITest
+{
+ void ITest.Test()
+ {
+ Assert.Pass();
+ }
+}
diff --git a/src/ServicePool.Tests/TestTypes/Test3.cs b/src/ServicePool.Tests/TestTypes/Test3.cs
new file mode 100644
index 0000000..fd84add
--- /dev/null
+++ b/src/ServicePool.Tests/TestTypes/Test3.cs
@@ -0,0 +1,38 @@
+// Test3.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+
+using System.Diagnostics.CodeAnalysis;
+
+namespace TheXDS.ServicePool.TestTypes;
+
+[ExcludeFromCodeCoverage]
+public class Test3 : Test1
+{
+}
diff --git a/src/ServicePool.Tests/TestTypes/Test4.cs b/src/ServicePool.Tests/TestTypes/Test4.cs
new file mode 100644
index 0000000..88acf31
--- /dev/null
+++ b/src/ServicePool.Tests/TestTypes/Test4.cs
@@ -0,0 +1,48 @@
+// Test4.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+#pragma warning disable IDE0290
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+
+namespace TheXDS.ServicePool.TestTypes;
+
+[ExcludeFromCodeCoverage]
+public class Test4
+{
+ public Test4(Random random, Test1 test1)
+ {
+ Random = random;
+ Test1 = test1;
+ }
+
+ public Random Random { get; }
+ public Test1 Test1 { get; }
+}
diff --git a/src/ServicePool.Tests/TestTypes/UninstantiableTest.cs b/src/ServicePool.Tests/TestTypes/UninstantiableTest.cs
new file mode 100644
index 0000000..9be86c0
--- /dev/null
+++ b/src/ServicePool.Tests/TestTypes/UninstantiableTest.cs
@@ -0,0 +1,45 @@
+// UninstantiableTest.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#pragma warning disable CS1591
+#pragma warning disable IDE0290
+#pragma warning disable IDE0060
+
+using System;
+using System.Collections;
+using System.Diagnostics.CodeAnalysis;
+
+namespace TheXDS.ServicePool.TestTypes;
+
+[ExcludeFromCodeCoverage]
+public class UninstantiableTest
+{
+ public UninstantiableTest(int x, Exception y, Guid z, IEnumerator a)
+ {
+ }
+}
diff --git a/src/ServicePool/DefaultDiscoveryEngine.cs b/src/ServicePool/DefaultDiscoveryEngine.cs
index 10e0a78..eccd636 100644
--- a/src/ServicePool/DefaultDiscoveryEngine.cs
+++ b/src/ServicePool/DefaultDiscoveryEngine.cs
@@ -37,8 +37,9 @@ namespace TheXDS.ServicePool;
///
///
/// This is used by default by
-/// and
-/// .
+/// ,
+///
+/// and other related overloads of these methods.
///
public class DefaultDiscoveryEngine : IDiscoveryEngine
{
diff --git a/src/ServicePool/Extensions/Common.cs b/src/ServicePool/Extensions/Common.cs
index d7f77c8..0675136 100644
--- a/src/ServicePool/Extensions/Common.cs
+++ b/src/ServicePool/Extensions/Common.cs
@@ -26,46 +26,43 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
-namespace TheXDS.ServicePool.Extensions
+namespace TheXDS.ServicePool.Extensions;
+
+///
+/// Includes a set of useful extension methods to work with ServicePool.
+///
+public static class Common
{
///
- /// Includes a set of useful extension methods to work with ServicePool.
+ /// Adds support for Fluent singleton registration on any object type.
///
- public static class Common
+ ///
+ /// Type of object to register into the pool.
+ ///
+ /// Instance to register.
+ /// Pool to register the singleton into.
+ /// The same instance as .
+ public static T RegisterInto(this T obj, PoolBase pool) where T : notnull
{
- ///
- /// Adds support for Fluent singleton registration on any object type.
- ///
- ///
- /// Type of object to register into the pool.
- ///
- /// Instance to register.
- /// Pool to register the singleton into.
- /// The same instance as .
- public static T RegisterInto(this T obj, ServicePool pool) where T : notnull
- {
- pool.RegisterNow(obj);
- return obj;
- }
+ pool.RegisterNow(obj);
+ return obj;
+ }
- ///
- /// Adds support for Fluent singleton registration on any object type.
- ///
- ///
- /// Type of object to register into the pool.
- ///
- /// Instance to register.
- /// Pool to register the singleton into.
- ///
- /// Value that determines if the singleton should be registered or not.
- ///
- ///
- /// The same instance as if
- /// is equal to ,
- /// otherwise.
- public static T? RegisterIntoIf(this T obj, ServicePool pool, bool condition) where T : notnull
- {
- return condition ? obj.RegisterInto(pool) : default;
- }
+ ///
+ /// Adds support for Fluent singleton registration on any object type.
+ ///
+ ///
+ /// Type of object to register into the pool.
+ ///
+ /// Instance to register.
+ /// Pool to register the singleton into.
+ ///
+ /// Value that determines if the singleton should be registered or not.
+ ///
+ ///
+ /// The same instance as .
+ public static T RegisterIntoIf(this T obj, PoolBase pool, bool condition) where T : notnull
+ {
+ return condition ? obj.RegisterInto(pool) : obj;
}
}
diff --git a/src/ServicePool/Extensions/DiscoverySupportExtensions.cs b/src/ServicePool/Extensions/DiscoverySupportExtensions.cs
new file mode 100644
index 0000000..83e0d25
--- /dev/null
+++ b/src/ServicePool/Extensions/DiscoverySupportExtensions.cs
@@ -0,0 +1,262 @@
+// DiscoverySupportExtensions.cs
+//
+// This file is part of ServicePool
+//
+// Author(s):
+// César Andrés Morgan
+//
+// Released under the MIT License (MIT)
+// Copyright © 2011 - 2022 César Andrés Morgan
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the “Software”), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+
+namespace TheXDS.ServicePool.Extensions;
+
+///
+/// Includes a set of extensions to extend the functionality of service pools
+/// to include service discovery functionality.
+///
+public static class DiscoverySupportExtensions
+{
+ ///
+ /// Tries to resolve a registered service of type
+ /// , and if not found, searches for any type
+ /// in the app domain that can be instantiated and returned as the
+ /// requested service.
+ ///
+ /// Type of service to get.
+ ///
+ /// Pool instance to discover the services from/onto.
+ ///
+ ///
+ /// If set to , in case a service of the
+ /// specified type hasn't been registered and a compatible type has
+ /// been discovered, the newly created instance will be registered
+ /// persistently in the pool. If set to , the
+ /// discovered service will not be added to the pool.
+ ///
+ ///
+ /// A registered service or a newly discovered one if it implements the
+ /// requested type, or in case that no
+ /// discoverable service for the requested type exists.
+ ///
+ ///
+ /// When discovering new services, if a service of a specific type is
+ /// found inside the pool, it will be gracefully skipped and not
+ /// instantiated again.
+ ///
+ public static T? Discover(this PoolBase pool, bool persistent = true) where T : notnull
+ {
+ return (T?)Discover(pool, typeof(T), persistent);
+ }
+
+ ///
+ /// Tries to resolve a registered service of the specified type, and if not
+ /// found, searches for any type that can be instantiated and returned as
+ /// the requested service.
+ ///
+ ///
+ /// Pool instance to discover the service from/onto.
+ ///
+ /// Type fo service to discover.
+ ///
+ /// If set to , in case a service of the
+ /// specified type hasn't been registered and a compatible type has
+ /// been discovered, the newly created instance will be registered
+ /// persistently in the pool. If set to , the
+ /// discovered service will not be added to the pool.
+ ///
+ ///
+ /// A registered service or a newly discovered one if it implements the
+ /// requested type, or in case that no
+ /// discoverable service for the requested type exists.
+ ///
+ public static object? Discover(this PoolBase pool, Type objectType, bool persistent = true)
+ {
+ return Discover(pool, objectType, new DefaultDiscoveryEngine(), persistent);
+ }
+
+ ///
+ /// Tries to resolve a registered service of type
+ /// , and if not found, searches for any type
+ /// that can be instantiated and returned as the requested service.
+ ///
+ /// Type of service to get.
+ ///
+ /// Pool instance to discover the service from/onto.
+ ///
+ ///
+ /// Discovery engine to use while searching for new instantiable types.
+ ///
+ ///
+ /// If set to , in case a service of the
+ /// specified type hasn't been registered and a compatible type has
+ /// been discovered, the newly created instance will be registered
+ /// persistently in the pool. If set to , the
+ /// discovered service will not be added to the pool.
+ ///
+ ///
+ /// A registered service or a newly discovered one if it implements the
+ /// requested type, or in case that no
+ /// discoverable service for the requested type exists.
+ ///
+ ///
+ /// When discovering new services, if a service of a specific type is
+ /// found inside the pool, it will be gracefully skipped and not
+ /// instantiated again.
+ ///
+ public static T? Discover(this PoolBase pool, IDiscoveryEngine discoveryEngine, bool persistent = true) where T : notnull
+ {
+ return (T?)Discover(pool, typeof(T), discoveryEngine, persistent);
+ }
+
+ ///
+ /// Tries to resolve a registered service of the specified type, and if not
+ /// found, searches for any type that can be instantiated and returned as
+ /// the requested service.
+ ///
+ ///
+ /// Pool instance to discover the service from/onto.
+ ///
+ /// Type fo service to discover.
+ ///
+ /// Discovery engine to use while searching for new instantiable types.
+ ///
+ ///
+ /// If set to , in case a service of the
+ /// specified type hasn't been registered and a compatible type has
+ /// been discovered, the newly created instance will be registered
+ /// persistently in the pool. If set to , the
+ /// discovered service will not be added to the pool.
+ ///
+ ///
+ /// A registered service or a newly discovered one if it implements the
+ /// requested type, or in case that no
+ /// discoverable service for the requested type exists.
+ ///
+ public static object? Discover(this PoolBase pool, Type objectType, IDiscoveryEngine discoveryEngine, bool persistent = true)
+ {
+ return pool.Resolve(objectType) ?? DiscoverAll(pool, discoveryEngine, objectType, persistent).FirstOrDefault();
+ }
+
+ ///
+ /// Discovers all the available service instances that implement the specified service type.
+ ///
+ ///
+ /// Pool instance to discover the services from/onto.
+ ///
+ ///
+ /// Discovery engine to use while searching for new instantiable types.
+ ///
+ /// Type of service to discover.
+ ///
+ /// If set to , in case a service of the
+ /// specified type hasn't been registered and a compatible type has
+ /// been discovered, the newly created instances will be registered
+ /// persistently in the pool. If set to , the
+ /// discovered services will not be added to the pool.
+ ///
+ ///
+ /// An enumeration of all discovered services.
+ ///
+ public static IEnumerable