Skip to content

Commit

Permalink
(GH-79) Add specific exception message in GenericStrategyProvider (#80)
Browse files Browse the repository at this point in the history
* .NET 6

* Added more specific exception message.

Co-authored-by: Urs Muntwyler <urs.muntwyler@bbtsoftware.ch>
  • Loading branch information
urs-muntwyler and Urs Muntwyler authored Jan 16, 2023
1 parent df23395 commit 9ea4068
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,4 @@
<ProjectReference Include="..\BBT.StrategyPattern\BBT.StrategyPattern.csproj" />
</ItemGroup>

<ItemGroup>
<Reference Include="System">
<HintPath>System</HintPath>
</Reference>
</ItemGroup>

</Project>
54 changes: 52 additions & 2 deletions src/BBT.StrategyPattern.Tests/WithIocTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace BBT.StrategyPattern.Tests
{
using System;
using BBT.StrategyPattern.Tests.Data;
using BBT.StrategyPattern.Tests.ExampleStrategyImpl;
using BBT.StrategyPattern.Tests.WithIoc;
Expand All @@ -19,7 +20,6 @@ public void WorksWithIocNinject()
var op1 = new Operator() { Operation = OperatorEnum.Addition };
var op2 = new Operator() { Operation = OperatorEnum.Subtraktion };


// IoC registrations
IKernel kernel = new StandardKernel();

Expand All @@ -39,5 +39,55 @@ public void WorksWithIocNinject()
strategy = kernel.Get<IGenericStrategyProvider<IOperatorStrategy, Operator>>().GetStrategy(op2);
strategy.DoCalculate(calc1).Should().Be(2);
}

[Fact]
public void MissingStrategies_ThrowsExpectedException()
{
// Prepare data
var calc1 = new CalculationInput() { Number1 = 5, Number2 = 3 };
var op1 = new Operator() { Operation = OperatorEnum.Addition };
var op2 = new Operator() { Operation = OperatorEnum.Subtraktion };

// IoC registrations (note: do not register any IOperatorStrategy strategy)
IKernel kernel = new StandardKernel();

kernel.Bind(typeof(IStrategyLocator<>)).To(typeof(NinjectStrategyLocator<>));
kernel.Bind<IGenericStrategyProvider<IOperatorStrategy, Operator>>().To<GenericStrategyProvider<IOperatorStrategy, Operator>>();

// Act
var act = () => kernel.Get<IGenericStrategyProvider<IOperatorStrategy, Operator>>().GetStrategy(op2);

// Assert
act.Should()
.Throw<InvalidOperationException>()
.WithMessage("No strategies of type IOperatorStrategy are available from the locator.");

}

[Fact]
public void MissingStrategyForCriteria_ThrowsExpectedException()
{
// Prepare data
var calc1 = new CalculationInput() { Number1 = 5, Number2 = 3 };
var op1 = new Operator() { Operation = OperatorEnum.Addition };
var op2 = new Operator() { Operation = OperatorEnum.Subtraktion };

// IoC registrations (note: do not register SubstractionStrategy)
IKernel kernel = new StandardKernel();

kernel.Bind(typeof(IStrategyLocator<>)).To(typeof(NinjectStrategyLocator<>));

kernel.Bind<IOperatorStrategy>().To<AdditionStrategy>();

kernel.Bind<IGenericStrategyProvider<IOperatorStrategy, Operator>>().To<GenericStrategyProvider<IOperatorStrategy, Operator>>();

// Act
var act = () => kernel.Get<IGenericStrategyProvider<IOperatorStrategy, Operator>>().GetStrategy(op2);

// Assert
act.Should()
.Throw<InvalidOperationException>()
.WithMessage("No strategy of type IOperatorStrategy available from the locator being responsible for criterion of type Operator.");
}
}
}
}
23 changes: 4 additions & 19 deletions src/BBT.StrategyPattern/BBT.StrategyPattern.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,11 @@
<DebugType>pdbonly</DebugType>
</PropertyGroup>

<!-- Workaround for malformed XML file in .NET Standard 2.0 (https://github.com/dotnet/standard/issues/1527) -->
<PropertyGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
<NoWarn>$(NoWarn);IDT001</NoWarn>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
<PackageDownload Include="NETStandard.Library.Ref" Version="[2.1.0]" />
<InheritDocReference Include="$([MSBuild]::EnsureTrailingSlash('$(NugetPackageRoot)'))netstandard.library.ref\2.1.0\ref\netstandard2.1\netstandard.xml" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.2.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.2">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="SauceControl.InheritDoc" Version="1.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
Expand All @@ -53,4 +34,8 @@
</AssemblyAttribute>
</ItemGroup>

<PropertyGroup>
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
</PropertyGroup>

</Project>
12 changes: 10 additions & 2 deletions src/BBT.StrategyPattern/GenericStrategyProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,18 @@ public TStrategy GetStrategy(TCriterion criterion)
// If no strategies for TStrategy can be found.
if (!strategies.Any())
{
throw new InvalidOperationException($"No strategies of {typeof(TStrategy).Name} are available from the locator.");
throw new InvalidOperationException($"No strategies of type {typeof(TStrategy).Name} are available from the locator.");
}

return strategies.Single(x => x.IsResponsible(criterion));
var strategy = strategies.SingleOrDefault(x => x.IsResponsible(criterion));

// If no strategy responsible for TCriterion can be found.
if (strategy == null)
{
throw new InvalidOperationException($"No strategy of type {typeof(TStrategy).Name} available from the locator being responsible for criterion of type {typeof(TCriterion).Name}.");
}

return strategy;
}
}
}

0 comments on commit 9ea4068

Please sign in to comment.