Flagger
Flagger is a small library which help you to set and unset (or toggle) a variable, field or property at the begin and end of an using scope. It is very useful for WPF properties, when you need to set a Dependency Property -- e.g. "IsWorking" -- while some background processing is being done to show and hide a panel using binding to a visibility property, or even to implement lightweight locks.
The purpose is to help switching values for a short period. It is tailored not only for bool
values (the most obvious usage), but for any type.
As Flagger is based on the IDisposable interface, it can be used with the using
instruction, and thus is exception-safe (who never ran into problems by not unsetting a flag?).
Flagger also provide methods to deal with recursive flag setting codes, allowing to setting and unsetting a flag only if it was not previously set, avoiding a recursive or nested method to inadvertently unset a flag prematurely.
How to use Flagger?
Before anything else, import most current version of the NuGet package to your project. It targets for both .NET Standard 1.0 and .NET Standard 2.0, so it can be used in any .NET Core project and in .NET Framework 4.0 or greater, including many other .NET Framework versions.
The most simple way to use Flagger is with the Flag static class methods. See these examples to learn more!
Flag.Toggle
1. Toggling boolean values withUse Flag.Toggle when you need to invert (toggle) momentarily the value of a bool
variable, field or property.
using Flagger;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Flagger.Samples.Toggle {
class Program {
//Boolean property to be toggled
static bool IsProcessing { get; set; } = false;
//Long working method which sets the property during operation to signal the UI
static async Task DoWork() {
// Should be false
Console.WriteLine($"{nameof(IsProcessing)} is {IsProcessing}");
// At the begin of its lifetime, the Flag<bool> returned by the Flag.Toggle will invert the
// initial value of IsProcessing
using(Flag.Toggle(() => IsProcessing)) {
await Task.Run(() => {
// long running operation
for(int i = 0; i < 10; i++) {
//Should be true
Console.WriteLine($"{nameof(IsProcessing)} is {IsProcessing}");
Thread.Sleep(1000);
}
});
// At the end of its lifetime, the Flag<bool> will invert the value of IsProcessing again
}
// Should be false again
Console.WriteLine($"{nameof(IsProcessing)} is {IsProcessing}");
}
static async Task Main(string[] args) {
await DoWork();
}
}
}
Flag.SetAndReset<T>
2. Setting and Resetting values withUse Flag.SetAndReset<T> when you need to set an arbitrary value to a field or property momentarily, and reset it back to its original value when done.
using Flagger;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Flagger.Samples.SetAndReset {
class Program {
//String property to be set
static string Status { get; set; } = "Idle";
//Long working method which sets the property during operation to signal the UI
static async Task DoWork() {
// Should be "Idle"
Console.WriteLine($"{nameof(Status)} is {Status}");
// At the begin of its lifetime, the Flag<string> returned by the Flag.SetAndReset will
// store the initial value of Status property ("Idle"), and set it to "Working"
using(Flag.SetAndReset(() => Status, "Working")) {
await Task.Run(() => {
// long running operation
for(int i = 0; i < 10; i++) {
//Should be "Working"
Console.WriteLine($"{nameof(Status)} is {Status}");
Thread.Sleep(1000);
}
});
// At the end of its lifetime, the Flag<string> will reset the value of Status back to
// "Idle"
}
// Should be "Idle" again
Console.WriteLine($"{nameof(Status)} is {Status}");
}
static async Task Main(string[] args) {
await DoWork();
}
}
}
Flag.SetAndUnset<T>
3. Setting and Resetting values withUse Flag.SetAndUnset<T> when you need to set an specific initial value to a field or property momentarily, and another specific final value when done.
If you need to set a bool
variable, field or property to true
and unset it to false
(a very common scenario), you can use the simpler boolean version of the Flag.SetAndUnset method.
using Flagger;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Flagger.Samples.SetAndUnset {
class Program {
//String property to be set
static string Status { get; set; } = "Idle";
//Long working method which sets the property during operation to signal the UI
static async Task DoWork() {
// Should be "Idle"
Console.WriteLine($"{nameof(Status)} is {Status}");
// At the begin of its lifetime, the Flag<string> returned by the Flag.SetAndUnset will
// set the Status property to "Working"
using(Flag.SetAndUnset(() => Status, "Working", "Done")) {
await Task.Run(() => {
// long running operation
for(int i = 0; i < 10; i++) {
//Should be "Working"
Console.WriteLine($"{nameof(Status)} is {Status}");
Thread.Sleep(1000);
}
});
// At the end of its lifetime, the Flag<string> will setvalue of Status to "Done"
}
// Should be "Done"
Console.WriteLine($"{nameof(Status)} is {Status}");
}
static async Task Main(string[] args) {
await DoWork();
}
}
}
Flag.SetAndUnsetIfUnset<T>
4. Setting and Unsetting values only if the initial value is equal to the unset value withUse Flag.SetAndUnsetIfUnset<T> when you need to set an specific initial value to a field or property momentarily, and a specific final value when done, but only if the initial value is equal to the final value (i.e. it was not set yet), in this case, not changing the flag at all.
This is specially useful in recursion scenarios, or when more than one method sets and unsets the same flag.
If you need to set a bool
variable, field or property to true
and unset it to false
only when the initial value of the variable, field or property is false
(another common scenario), you can use the simpler boolean version of the Flag.SetAndUnsetIfUnset method.
using Flagger;
using System;
namespace Flagger.Samples.SetAndUnsetIfUnset {
class Program {
//String property to be set
static string Status { get; set; } = "Idle";
//Recursive method which sets the property during operation to signal the UI
static void DoWork(int recursionLevel = 0) {
string padSpaces = new String(' ', recursionLevel);
// Should be "Idle" in first recursion level, and "Busy" otherwise
Console.WriteLine($"{padSpaces}At {nameof(recursionLevel)} {recursionLevel}, " +
$"before {nameof(Flag.SetAndUnsetIfUnset)}, {nameof(Status)} is {Status}");
// At the begin of its lifetime, the Flag<string> returned by the Flag.SetAndUnsetIfUnset will
// set the Status property to "Busy" if it is not already "Busy"
using(Flag.SetAndUnsetIfUnset(() => Status, "Busy", "Done")) {
// Should be "Busy"
Console.WriteLine($"{padSpaces} => At beginning of {nameof(Flag.SetAndUnsetIfUnset)}, " +
$"{nameof(Status)} is {Status}");
// Call the method recursively
if(recursionLevel < 3) {
DoWork(recursionLevel + 1);
}
// Should (still) be "Busy"
Console.WriteLine($"{padSpaces} => At end of {nameof(Flag.SetAndUnsetIfUnset)}, " +
$"{nameof(Status)} is {Status}");
// At the end of its lifetime, the Flag<string> only will set the value of Status to "Done"
// if it was not previously "Busy"
}
// Should be "Done" in first recursion level, and "Busy" otherwise
Console.WriteLine($"{padSpaces}At {nameof(recursionLevel)} {recursionLevel}, " +
$"after {nameof(Flag.SetAndUnsetIfUnset)}, {nameof(Status)} is {Status}");
}
static void Main(string[] args) {
DoWork();
}
}
}
Class Reference
Class | Description |
---|---|
Flag | Contains several methods which allows to configure contextual flags |
Flag<T> | Allows for setting a value to the supplied member while the context lasts, and resetting the value on the context disposal |
Flag
Contains several methods which allows to configure contextual flags
Method | Description |
---|---|
Flag.Toggle (member) | Toggles the value of a member |
Flag.SetAndReset<T> (member, setValue) | Set and reset the value of a member |
Flag.SetAndUnset<T> (member, setValue, unsetValue) | Set and unset the value of a member |
Flag.SetAndUnset (member) | Set and unset the value of a boolean member |
Flag.SetAndUnsetIfUnset<T> (member, setValue, unsetValue) | Set and unset the value of a member if it is currently unset |
Flag.SetAndUnsetIfUnset (member) | Set and unset the value of a boolean member if it is currently false |
Flag.Toggle(member)
Toggles (inverts) the value of the supplied boolean member
Parameter Name | Description |
---|---|
member | Expression<Func<Boolean>> Lambda expression which indicates the boolean member to be toggled. |
Returns
Flag<Boolean>
Flag context which toggles the boolean member
Flag.SetAndReset<T>(member, setValue)
Sets the value of the supplied boolean member to the provided value, and reset it to its original value on the context disposal
Parameter Name | Description |
---|---|
member | Expression<Func<T>> Lambda expression which indicates the member to be set. |
setValue | T The value to be set at the context creation |
Returns
Flag<T>
Flag context which sets and resets the member value
Flag.SetAndUnset<T>(member, setValue, unsetValue)
Sets the value of the supplied member to the provided set value, and set it to the provided unset value on the context disposal
Parameter Name | Description |
---|---|
member | Expression<Func<T>> Lambda expression which indicates the member to be set. |
setValue | <T> The value to be set at the context creation |
unsetValue | <T> The value to be set at the contex disposal |
Returns
Flag<T>
Flag context which sets and unsets the member value
Flag.SetAndUnset(member)
Sets the value of the supplied boolean member to true on context creation, and set it to false on the context disposal
Parameter Name | Description |
---|---|
member | Expression<Func<Boolean>> Lambda expression which indicates the boolean member to be toggled. |
Returns
Flag<Boolean>
Flag context which sets and unsets the member value
Flag.SetAndUnsetIfUnset<T>(member, setValue, unsetValue)
If the current value of the supplied member is not equal to the setValue parameter value, set it to the setValue on context creation, and set it to the unsetValue parameter value on the context disposal. Otherwise, keeps it unchanged;
Parameter Name | Description |
---|---|
member | Expression<Func<T>> Lambda expression which indicates the member to be set. |
setValue | <T> The value to be set at the context creation |
unsetValue | <T> The value to be set at the contex disposal |
Returns
Flag<T>
Flag context which sets and unsets the member value
Flag.SetAndUnsetIfUnset(member)
If the current value of the supplied boolean member is false, set it to true on context creation, and set it to false on the context disposal. Otherwise, keeps it unchanged;
Parameter Name | Description |
---|---|
member | Expression<Func<Boolean>> Lambda expression which indicates the boolean member to be toggled. |
Returns
Flag<Boolean>
Flag context which sets and unsets the member value
Flag <T>
Allows for setting a value to the supplied member while the context lasts, and resetting the value on the context disposal. You cannot instantiate this class directly, only through one of the Flag static class methods. Also, the only possible interaction with this class, besides creating it, which sets the initial value of a flag, is disposing it, which unsets the value of the flag. The specific conditional behaviors of toggling, settting-resetting, setting-unsetting and non-recursively-set-unset are provided by the Flag static class methods.
Type Parameters
- T - The type of the member to be set and reset.
Dispose
Disposes of the flag context, resetting the supplied member value.