You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+31-43Lines changed: 31 additions & 43 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,5 @@
1
1
# Light.GuardClauses
2
-
**A lightweight library for expressive Guard Clauses with conditional compilation in .NET.**
3
-
4
-
[](https://youtu.be/NI0rVG6VbXo)
2
+
**A lightweight .NET library for expressive Guard Clauses.**
5
3
6
4
## Why do I need it?
7
5
@@ -22,6 +20,21 @@ public class Foo
22
20
}
23
21
```
24
22
23
+
Since v2.0.0, you can also directly use the return value of assertion methods to chain multiple assertions or, as in the following example, directly set the parameter to a field:
24
+
25
+
```csharp
26
+
publicclassFoo
27
+
{
28
+
privatereadonlyIBar_bar;
29
+
30
+
publicFoo(IBarbar)
31
+
{
32
+
// You can also use the return value of the assertion methods to e.g. directly set a field
33
+
_bar=bar.MustNotBeNull();
34
+
}
35
+
}
36
+
```
37
+
25
38
There is a vast variety of scenarios where Light.GuardClauses can support you, e.g. with GUIDs and numeric values:
26
39
27
40
```csharp
@@ -35,51 +48,28 @@ public void SetMovieRating(Guid movieId, int numberOfStars)
35
48
}
36
49
```
37
50
38
-
Inspired by [FluentAssertions](https://github.com/dennisdoomen/FluentAssertions), there are many more methods tailored for strings, `IComparable<T>`, `IEnumerable<T>`, `IEquatable<T>`, and `IDictionary<T>`. See a list of all of them [in the release notes](https://github.com/feO2x/Light.GuardClauses/releases) or discover them on the fly through IntelliSense - all the methods are fully documented. Just be sure to add the following `using` statement at the top of your code files to see the extension methods: `using Light.GuardClauses;`.
51
+
Inspired by [FluentAssertions](https://github.com/dennisdoomen/FluentAssertions), there are many more methods tailored for strings, URIs, `DateTime`, `IComparable<T>`, `IEnumerable<T>`, `IEquatable<T>`, and `IDictionary<T>`. See a list of all of them [in the release notes](https://github.com/feO2x/Light.GuardClauses/releases) or discover them on the fly via IntelliSense - all the methods are fully documented. Just be sure to add the following `using` statement at the top of your code files to see the extension methods: `using Light.GuardClauses;`.
39
52
40
53
## Where do I get it?
41
54
42
55
[Download the assembly via NuGet](https://www.nuget.org/packages/Light.GuardClauses/): `Install-Package Light.GuardClauses` - Or use the code from this repo.
43
56
44
-
Light.GuardClauses is a Portable Class Library with support for profile 259. This means it is compatible with e.g. .NET 4.5 or later, .NET Core 1.0 and UWP (use "PackageTargetFallback" in csproj or "imports" in project.json), Windows 8 / 8.1 Store Apps, and Windows Phone 8.1 / Windows Phone 8 Silverlight.
45
-
46
-
**Important: if the target project uses the new .NET Core csproj format or project.json, the COMPILE_ASSERTIONS symbol is not set automatically when installing the NuGet package - you have to set it manually in this case. See the [Conditional Compilation](https://github.com/feO2x/Light.GuardClauses#conditional-compilation) section below for more info.**
57
+
Light.GuardClauses is a .NET Standard 1.0 library since v2.0.0 (before it was a PCL with profile 259). This means it is compatible with e.g. .NET 4.5 or later, .NET Core 1.0 and UWP, Mono 4.6, Xamarin.iOS 10.0, Xamarin.Android 7.0, Windows 8 / 8.1 Store Apps, and Windows Phone 8.1 / Windows Phone 8 Silverlight.
47
58
48
59
## And what's the difference to other assertion libraries?
49
60
50
-
Light.GuardClauses is specifically tailored for the scenario of creating precondition checks in production code. While the purpose of many other libraries is to provide a fluent syntax for assertions in automated tests, Light.GuardClauses does not provide these method-chaining capabilities, mainly for two reasons: to be high-performant as all checks involve only static method calls which create as less objects as possible (to keep the pressure on the Garbage Collector low), and to provide conditional compilation.
51
-
52
-
## Conditional Compilation
53
-
54
-
The methods of Light.GuardClauses are marked with the [ConditionalAttribute](https://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute(v=vs.110).aspx) so that you can include or exclude the calls to these methods when you build your project. To exclude the calls to the Light.GuardClauses methods, go to the Build tab in the project properties and remove the compilation symbol "COMPILE_ASSERTIONS". By default, this symbol is set when you install Light.GuardClauses via NuGet.
55
-
56
-
**Important: the COMPILE_ASSERTIONS symbol is not set automatically in projects that use the new .NET Core csproj format or project.json. You have to set it manually in this case, e.g. in the project properties.**
**Alternatively, you can add the following XML to the first `PropertyGroup` in the new csproj format:**
61
+
Light.GuardClauses is specifically tailored for the scenario of creating precondition checks in production code. While the purpose of many other libraries is to provide a fluent syntax for assertions in automated tests, Light.GuardClauses achieves the following two goals:
**Or the following JSON under the root object in project.json:**
69
-
70
-
```json
71
-
"buildOptions": {
72
-
"define": [ "COMPILE_ASSERTIONS" ]
73
-
}
74
-
```
63
+
1) Light.GuardClauses is high-performant as all checks involve only static method calls which create as less objects as possible (to keep the pressure on the Garbage Collector low)
64
+
2) Light.GuardClauses provides meaningful exception messages that you would expect from production code. Additionally, you can easily customize the message or the expception being thrown for every assertion call.
75
65
76
-
Although you cannot use method chaining (because methods marked with the [ConditionalAttribute](https://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute(v=vs.110).aspx) cannot have a return value), the ability to selectively include or exclude these precondition checks gives you a lot of flexibility regarding performance: during development, you can enable them to fail fast, and if you absolutely need the performance squeeze, you can disable them for your production deployment - this is perfectly in line with Bertrand Meyer's Design by Contract where you can also enable or disable assertions (by the way, read his book "Object-Oriented Software Construction" if you haven't - it's a necessary read for any O-O dev in my opinion).
66
+
Check out the following section to learn how you can customize the resulting exceptions when precondition checks fail.
77
67
78
68
## Customizing messages and exceptions
79
69
80
70
Every extension method of Light.GuardClauses has three optional parameters: **parameterName**, **message** and **exception**. With these, you can customize the outcome of an assertion:
81
71
82
-
***parameterName** lets you inject the name of the parameter that is checked into the resulting exception message. By default, the standard exception messages use e.g. "The value"or "The string" to talk about the subject - these parts are exchanged when you specify the name of the parameter. My advise is to not use paramterName when developing application-specific code, but if you create framework / library or any other type of reusable code, it is better to use this parameterName so that exception messages immediately point to the erroneous parameter.
72
+
***parameterName** lets you inject the name of the parameter being checked into the resulting exception message. By default, the standard exception messages use e.g. "The value", "The string", or "The URI" to talk about the subject - these parts are exchanged when you specify the name of the parameter. My advise is to not use `paramterName` when developing application-specific code, but if you create framework, library, or any other type of reusable code, it is better to use `parameterName` so that exception messages immediately point to the erroneous parameter.
83
73
***message** lets you exchange the entire exception message if you are not satisfied with the default message in your current context.
84
74
***exception** lets you specify a delegate creating an exception object that is thrown instead of the default exception.
85
75
@@ -143,11 +133,11 @@ Of course, you can write your own extension methods, too.
@@ -164,11 +154,11 @@ Your extension method is cool and you think other developers can benefit from it
164
154
165
155
Light.GuardClausesuses [xunit.net](https://github.com/xunit/xunit) as the framework for automated tests and [FluentAssertions](https://github.com/dennisdoomen/FluentAssertions) for assertions within test methods. Please do not use any other frameworks when you want to integrate your own extension methods within Light.GuardClauses.Tests. Also, I would advise you to create one test class per assertion method.
* Because writing tests for custom messages and custom exceptions for all extension methods is tedious, I created a little bit of infrastructure that does most of the heavy lifting for you. This infrastructure is implemented in `CustomMessagesAndCustomExceptionsTests` and the types in the sub-namespace `CustomMessagesAndExceptions`. All you have to do is implement the `ICustomMessageAndExceptionTestDataProvider` interface in your own test class. In the only method `PopulateTestDataForCustomExceptionAndCustomMessageTests`of this interface, you get a `CustomMessageAndExceptionTestData` object as a parameter that you can use to populate as many `CustomExceptionTest` and `CustomMessageTest` instances as you like. Check the existing test classes or the example below to see how it's done. Just be aware that `CustomMessagesAndCustomExceptionsTests` also checks if your test class implements the said interface, and if not will tell you so in the test runs. If you do not implement an assertion extension method, you can whitelist your test class in the `OmmitedTestClasses` field.
Light.GuardClausesisdevelopedaspartofthe"iRescYou"researchproject, conductedatthe [UniversityHospitalofRegensburg](http://www.uniklinikum-regensburg.de/e/index.php) and the [University of Applied Sciences Regensburg](https://www.oth-regensburg.de/en.html), funded by the [Bavarian State Ministry of Health Care](http://www.stmgp.bayern.de/).
206
+
Light.GuardClauseswasinitiallydevelopedaspartofthe[iRescYouresearchproject](http://www.irescyou.de/), conducted at the [University Hospital of Regensburg](http://www.uniklinikum-regensburg.de/e/index.php) and the [University of Applied Sciences Regensburg](https://www.oth-regensburg.de/en.html), funded by the [Bavarian State Ministry of Health and Care](http://www.stmgp.bayern.de/).
219
207
220
208
Thanksto [xunit.net](https://github.com/xunit/xunit) and [FluentAssertions](https://github.com/dennisdoomen/FluentAssertions) - I use these frameworks every day!
221
-
And [VisualStudio](https://www.visualstudio.com/) together with [R#](https://www.jetbrains.com/dotnet/) is awesome!
209
+
And [VisualStudio](https://www.visualstudio.com/) in combination with [R#](https://www.jetbrains.com/dotnet/) is awesome!
0 commit comments