diff --git a/.vscode/settings.json b/.vscode/settings.json
index 0a8ba99..f7754b1 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,3 +1,7 @@
{
+ "cSpell.words": [
+ "autofac",
+ "xunit"
+ ],
"omnisharp.enableEditorConfigSupport": true
}
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 2354883..70e1c3b 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -1,21 +1,9 @@
{
"tasks": [
- {
- "args": [
- "watch",
- "run",
- "${workspaceFolder}/test/Autofac.Pooling.Tests/Autofac.Pooling.Tests.csproj",
- "/property:GenerateFullPaths=true",
- "/consoleloggerparameters:NoSummary"
- ],
- "command": "dotnet",
- "label": "watch",
- "problemMatcher": "$msCompile",
- "type": "process"
- },
{
"args": [
"build",
+ "Autofac.Pooling.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
diff --git a/Directory.Build.targets b/Directory.Build.targets
deleted file mode 100644
index 341027f..0000000
--- a/Directory.Build.targets
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/build/Source.ruleset b/build/Source.ruleset
index 459e4e0..8994858 100644
--- a/build/Source.ruleset
+++ b/build/Source.ruleset
@@ -1,9 +1,11 @@
-
-
+
+
-
-
+
+
+
+
@@ -12,23 +14,45 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/Test.ruleset b/build/Test.ruleset
index 3c26c01..b64a37a 100644
--- a/build/Test.ruleset
+++ b/build/Test.ruleset
@@ -1,16 +1,14 @@
-
-
+
+
-
-
-
-
+
+
-
-
-
+
-
+
+
+
@@ -20,37 +18,93 @@
-
-
-
+
-
+
-
-
-
+
+
+
+
+
-
+
-
+
-
+
+
+
-
+
-
+
-
+
-
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -58,11 +112,11 @@
-
+
-
+
-
+
@@ -82,6 +136,13 @@
+
+
+
+
+
+
+
diff --git a/src/Autofac.Pooling/Autofac.Pooling.csproj b/src/Autofac.Pooling/Autofac.Pooling.csproj
index 1e71b41..7954479 100644
--- a/src/Autofac.Pooling/Autofac.Pooling.csproj
+++ b/src/Autofac.Pooling/Autofac.Pooling.csproj
@@ -8,6 +8,8 @@
../../Autofac.snk
true
../../build/Source.ruleset
+ AllEnabledByDefault
+ true
false
false
false
@@ -32,27 +34,29 @@
true
$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
-
+
+
+
-
-
-
All
All
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
-
True
@@ -70,7 +74,6 @@
RegistrationExtensionsResources.resx
-
ResXFileCodeGenerator
@@ -85,5 +88,4 @@
RegistrationExtensionsResources.Designer.cs
-
diff --git a/src/Autofac.Pooling/AutofacPooledObjectPolicy.cs b/src/Autofac.Pooling/AutofacPooledObjectPolicy.cs
index 8665959..8b202c4 100644
--- a/src/Autofac.Pooling/AutofacPooledObjectPolicy.cs
+++ b/src/Autofac.Pooling/AutofacPooledObjectPolicy.cs
@@ -10,7 +10,7 @@ namespace Autofac.Pooling;
/// Provides the needed for creating/returning objects in the pool in an Autofac way.
///
/// The type of object being pooled.
-internal class AutofacPooledObjectPolicy : IPooledObjectPolicy
+internal sealed class AutofacPooledObjectPolicy : IPooledObjectPolicy
where TPooledObject : class
{
private readonly Service _poolInstanceService;
diff --git a/src/Autofac.Pooling/PoolService.cs b/src/Autofac.Pooling/PoolService.cs
index 358cb76..1faae61 100644
--- a/src/Autofac.Pooling/PoolService.cs
+++ b/src/Autofac.Pooling/PoolService.cs
@@ -11,7 +11,7 @@ namespace Autofac.Pooling;
///
/// Defines a service used to access an , ensuring that each pooled item registration gets a different pool.
///
-internal class PoolService : Service, IEquatable
+internal sealed class PoolService : Service, IEquatable
{
private readonly IComponentRegistration _pooledItemRegistration;
diff --git a/src/Autofac.Pooling/PooledLifetime.cs b/src/Autofac.Pooling/PooledLifetime.cs
index bfed629..4398da7 100644
--- a/src/Autofac.Pooling/PooledLifetime.cs
+++ b/src/Autofac.Pooling/PooledLifetime.cs
@@ -8,6 +8,7 @@ namespace Autofac.Pooling;
///
/// Lifetime wrapper to help us detect if we finished registering in a pooled configuration.
///
+[SuppressMessage("S2094", "S2094", Justification = "Lifetimes are classes, not interfaces. Changing this would be a breaking change.")]
public class PooledLifetime : CurrentScopeLifetime
{
}
diff --git a/test/Autofac.Pooling.Test/Autofac.Pooling.Test.csproj b/test/Autofac.Pooling.Test/Autofac.Pooling.Test.csproj
index f67c43d..83c24e7 100644
--- a/test/Autofac.Pooling.Test/Autofac.Pooling.Test.csproj
+++ b/test/Autofac.Pooling.Test/Autofac.Pooling.Test.csproj
@@ -2,8 +2,13 @@
net10.0
../../build/Test.ruleset
+ AllEnabledByDefault
+ true
false
+
+
+
all
@@ -15,6 +20,10 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/test/Autofac.Pooling.Test/Shared/IPooledService.cs b/test/Autofac.Pooling.Test/Common/IPooledService.cs
similarity index 80%
rename from test/Autofac.Pooling.Test/Shared/IPooledService.cs
rename to test/Autofac.Pooling.Test/Common/IPooledService.cs
index 144234e..951e569 100644
--- a/test/Autofac.Pooling.Test/Shared/IPooledService.cs
+++ b/test/Autofac.Pooling.Test/Common/IPooledService.cs
@@ -1,4 +1,4 @@
-namespace Autofac.Pooling.Tests.Shared;
+namespace Autofac.Pooling.Tests.Common;
public interface IPooledService
{
diff --git a/test/Autofac.Pooling.Test/Common/OtherPooledComponent.cs b/test/Autofac.Pooling.Test/Common/OtherPooledComponent.cs
new file mode 100644
index 0000000..edbf163
--- /dev/null
+++ b/test/Autofac.Pooling.Test/Common/OtherPooledComponent.cs
@@ -0,0 +1,10 @@
+namespace Autofac.Pooling.Tests.Common;
+
+public class OtherPooledComponent : IPooledService
+{
+ public int GetCalled => 0;
+
+ public int ReturnCalled => 0;
+
+ public int DisposeCalled => 0;
+}
diff --git a/test/Autofac.Pooling.Test/Shared/PoolTrackingPolicy.cs b/test/Autofac.Pooling.Test/Common/PoolTrackingPolicy.cs
similarity index 86%
rename from test/Autofac.Pooling.Test/Shared/PoolTrackingPolicy.cs
rename to test/Autofac.Pooling.Test/Common/PoolTrackingPolicy.cs
index 2365abe..7fa7cb3 100644
--- a/test/Autofac.Pooling.Test/Shared/PoolTrackingPolicy.cs
+++ b/test/Autofac.Pooling.Test/Common/PoolTrackingPolicy.cs
@@ -3,7 +3,7 @@
using System.Threading;
using Autofac.Core;
-namespace Autofac.Pooling.Tests.Shared;
+namespace Autofac.Pooling.Tests.Common;
public class PoolTrackingPolicy : DefaultPooledRegistrationPolicy
where TLimit : class
@@ -14,6 +14,8 @@ public class PoolTrackingPolicy : DefaultPooledRegistrationPolicy parameters, Func getFromPool)
{
+ ArgumentNullException.ThrowIfNull(getFromPool);
+
Interlocked.Increment(ref _outOfPool);
return getFromPool();
diff --git a/test/Autofac.Pooling.Test/Shared/PooledComponent.cs b/test/Autofac.Pooling.Test/Common/PooledComponent.cs
similarity index 61%
rename from test/Autofac.Pooling.Test/Shared/PooledComponent.cs
rename to test/Autofac.Pooling.Test/Common/PooledComponent.cs
index 5791620..ffbed02 100644
--- a/test/Autofac.Pooling.Test/Shared/PooledComponent.cs
+++ b/test/Autofac.Pooling.Test/Common/PooledComponent.cs
@@ -2,8 +2,9 @@
using System.Collections.Generic;
using Autofac.Core;
-namespace Autofac.Pooling.Tests.Shared;
+namespace Autofac.Pooling.Tests.Common;
+[SuppressMessage("CA1063", "CA1063", Justification = "Dispose remains simple here for testing.")]
public class PooledComponent : IPooledService, IPooledComponent, IDisposable
{
public int GetCalled
@@ -21,7 +22,7 @@ public int DisposeCalled
get; private set;
}
- public void OnGetFromPool(IComponentContext ctxt, IEnumerable parameters)
+ public void OnGetFromPool(IComponentContext context, IEnumerable parameters)
{
GetCalled++;
}
@@ -31,6 +32,7 @@ public void OnReturnToPool()
ReturnCalled++;
}
+ [SuppressMessage("CA1063", "CA1063", Justification = "Dispose remains simple here for testing.")]
public void Dispose()
{
DisposeCalled++;
diff --git a/test/Autofac.Pooling.Test/ConcurrencyTests.cs b/test/Autofac.Pooling.Test/ConcurrencyTests.cs
index 29f5bf5..a73c2e7 100644
--- a/test/Autofac.Pooling.Test/ConcurrencyTests.cs
+++ b/test/Autofac.Pooling.Test/ConcurrencyTests.cs
@@ -5,7 +5,7 @@
using System.Threading;
using System.Threading.Tasks;
using Autofac.Core;
-using Autofac.Pooling.Tests.Shared;
+using Autofac.Pooling.Tests.Common;
using Xunit;
namespace Autofac.Pooling.Test;
@@ -22,14 +22,18 @@ public async Task CanUsePoolConcurrently()
var container = builder.Build();
- await Task.WhenAll(Enumerable.Range(0, 2000).Select(i => Task.Run(() =>
+ var exception = await Record.ExceptionAsync(async () =>
{
- using var scope = container.BeginLifetimeScope();
+ await Task.WhenAll(Enumerable.Range(0, 2000).Select(i => Task.Run(() =>
+ {
+ using var scope = container.BeginLifetimeScope();
- scope.Resolve();
- })));
+ scope.Resolve();
+ })));
- container.Dispose();
+ container.Dispose();
+ });
+ Assert.Null(exception);
}
[Fact]
@@ -37,7 +41,7 @@ public async Task CanUsePoolConcurrentlyWithCustomPolicyToBlockOnMaxUsage()
{
var builder = new ContainerBuilder();
- var blockingPolicy = new BlockingPolicy(4);
+ using var blockingPolicy = new BlockingPolicy(4);
builder.RegisterType().As()
.PooledInstancePerLifetimeScope(blockingPolicy);
@@ -56,10 +60,11 @@ await Task.WhenAll(Enumerable.Range(0, 10000).Select(i => Task.Run(() =>
container.Dispose();
}
- private class BlockingPolicy : DefaultPooledRegistrationPolicy
+ private class BlockingPolicy : DefaultPooledRegistrationPolicy, IDisposable
where TLimit : class
{
private readonly SemaphoreSlim _semaphore;
+ private bool _disposedValue;
public BlockingPolicy(int maxConcurrentInstances) : base(maxConcurrentInstances)
{
@@ -83,5 +88,25 @@ public override bool Return(TLimit pooledObject)
return base.Return(pooledObject);
}
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ _semaphore.Dispose();
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
}
}
diff --git a/test/Autofac.Pooling.Test/DisposableTests.cs b/test/Autofac.Pooling.Test/DisposableTests.cs
index cf59a18..d903072 100644
--- a/test/Autofac.Pooling.Test/DisposableTests.cs
+++ b/test/Autofac.Pooling.Test/DisposableTests.cs
@@ -1,5 +1,5 @@
using Autofac.Features.OwnedInstances;
-using Autofac.Pooling.Tests.Shared;
+using Autofac.Pooling.Tests.Common;
using Xunit;
namespace Autofac.Pooling.Test;
diff --git a/test/Autofac.Pooling.Test/ImplicitRelationshipTests.cs b/test/Autofac.Pooling.Test/ImplicitRelationshipTests.cs
index e0a81c4..29b2f97 100644
--- a/test/Autofac.Pooling.Test/ImplicitRelationshipTests.cs
+++ b/test/Autofac.Pooling.Test/ImplicitRelationshipTests.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using Autofac.Features.Metadata;
using Autofac.Features.OwnedInstances;
-using Autofac.Pooling.Tests.Shared;
+using Autofac.Pooling.Tests.Common;
using Xunit;
namespace Autofac.Pooling.Test;
@@ -237,7 +237,7 @@ public void CanResolveCollectionOfTwoDifferentPoolsOfSameLimitType()
using (var scope1 = container.BeginLifetimeScope())
{
- var set = scope1.Resolve>();
+ scope1.Resolve>();
// The important point is that each pool goes up by one, meaning that we can track different pools
// for the same limit type.
diff --git a/test/Autofac.Pooling.Test/LifetimeScopeTests.cs b/test/Autofac.Pooling.Test/LifetimeScopeTests.cs
index 3116bed..2a2cc28 100644
--- a/test/Autofac.Pooling.Test/LifetimeScopeTests.cs
+++ b/test/Autofac.Pooling.Test/LifetimeScopeTests.cs
@@ -1,5 +1,5 @@
using Autofac.Core;
-using Autofac.Pooling.Tests.Shared;
+using Autofac.Pooling.Tests.Common;
using Xunit;
namespace Autofac.Pooling.Test;
diff --git a/test/Autofac.Pooling.Test/PolicyTests.cs b/test/Autofac.Pooling.Test/PolicyTests.cs
index ab302c2..b3af42d 100644
--- a/test/Autofac.Pooling.Test/PolicyTests.cs
+++ b/test/Autofac.Pooling.Test/PolicyTests.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Autofac.Core;
-using Autofac.Pooling.Tests.Shared;
+using Autofac.Pooling.Tests.Common;
using Xunit;
namespace Autofac.Pooling.Test;
@@ -144,11 +144,9 @@ public void PolicyCanSeeParametersFromThePooledServiceResolve()
var container = builder.Build();
- IPooledService pooledInstance;
-
using (var scope = container.BeginLifetimeScope())
{
- pooledInstance = scope.Resolve(new NamedParameter("Val1", 123), new TypedParameter(typeof(int), 456));
+ var _ = scope.Resolve(new NamedParameter("Val1", 123), new TypedParameter(typeof(int), 456));
}
Assert.Collection(policyReceivedParameters,
diff --git a/test/Autofac.Pooling.Test/PooledComponentTests.cs b/test/Autofac.Pooling.Test/PooledComponentTests.cs
index d511bd9..08fb98c 100644
--- a/test/Autofac.Pooling.Test/PooledComponentTests.cs
+++ b/test/Autofac.Pooling.Test/PooledComponentTests.cs
@@ -1,5 +1,5 @@
using Autofac.Features.OwnedInstances;
-using Autofac.Pooling.Tests.Shared;
+using Autofac.Pooling.Tests.Common;
using Xunit;
namespace Autofac.Pooling.Test;
diff --git a/test/Autofac.Pooling.Test/PoolingTests.cs b/test/Autofac.Pooling.Test/PoolingTests.cs
index 79d7cc6..26a63a5 100644
--- a/test/Autofac.Pooling.Test/PoolingTests.cs
+++ b/test/Autofac.Pooling.Test/PoolingTests.cs
@@ -1,7 +1,7 @@
-using Autofac.Pooling.Tests.Shared;
+using Autofac.Pooling.Tests.Common;
using Xunit;
-namespace Autofac.Pooling.Tests;
+namespace Autofac.Pooling.Test;
public class PoolingTest
{
diff --git a/test/Autofac.Pooling.Test/RegistrationExtensionsTests.cs b/test/Autofac.Pooling.Test/RegistrationExtensionsTests.cs
index 6a0505f..b3b7025 100644
--- a/test/Autofac.Pooling.Test/RegistrationExtensionsTests.cs
+++ b/test/Autofac.Pooling.Test/RegistrationExtensionsTests.cs
@@ -1,6 +1,6 @@
using System;
using Autofac.Builder;
-using Autofac.Pooling.Tests.Shared;
+using Autofac.Pooling.Tests.Common;
using Xunit;
namespace Autofac.Pooling.Test;
@@ -17,6 +17,7 @@ public void RequiresCallbackContainer()
}
[Fact]
+ [SuppressMessage("CA2000", "CA2000", Justification = "The container will dispose of the object.")]
public void NoProvidedInstances()
{
var builder = new ContainerBuilder();
diff --git a/test/Autofac.Pooling.Test/Shared/OtherPooledComponent.cs b/test/Autofac.Pooling.Test/Shared/OtherPooledComponent.cs
deleted file mode 100644
index f30acbe..0000000
--- a/test/Autofac.Pooling.Test/Shared/OtherPooledComponent.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Autofac.Pooling.Tests.Shared;
-
-public class OtherPooledComponent : IPooledService
-{
- public int GetCalled => throw new System.NotImplementedException();
-
- public int ReturnCalled => throw new System.NotImplementedException();
-
- public int DisposeCalled => throw new System.NotImplementedException();
-}