diff --git a/Unosquare.Swan.Lite/Abstractions/AtomicTypeBase.cs b/Unosquare.Swan.Lite/Abstractions/AtomicTypeBase.cs
index ab352db..3d61fdd 100644
--- a/Unosquare.Swan.Lite/Abstractions/AtomicTypeBase.cs
+++ b/Unosquare.Swan.Lite/Abstractions/AtomicTypeBase.cs
@@ -1,243 +1,228 @@
-namespace Unosquare.Swan.Abstractions
-{
- using System;
- using System.Threading;
-
+using System;
+using System.Threading;
+
+namespace Unosquare.Swan.Abstractions {
+ ///
+ /// Provides a generic implementation of an Atomic (interlocked) type
+ ///
+ /// Idea taken from Memory model and .NET operations in article:
+ /// http://igoro.com/archive/volatile-keyword-in-c-memory-model-explained/.
+ ///
+ /// The structure type backed by a 64-bit value.
+ public abstract class AtomicTypeBase : IComparable, IComparable, IComparable>, IEquatable, IEquatable>
+ where T : struct, IComparable, IComparable, IEquatable {
+ private Int64 _backingValue;
+
///
- /// Provides a generic implementation of an Atomic (interlocked) type
- ///
- /// Idea taken from Memory model and .NET operations in article:
- /// http://igoro.com/archive/volatile-keyword-in-c-memory-model-explained/.
+ /// Initializes a new instance of the class.
///
- /// The structure type backed by a 64-bit value.
- public abstract class AtomicTypeBase : IComparable, IComparable, IComparable>, IEquatable, IEquatable>
- where T : struct, IComparable, IComparable, IEquatable
- {
- private long _backingValue;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The initial value.
- protected AtomicTypeBase(long initialValue)
- {
- BackingValue = initialValue;
- }
-
- ///
- /// Gets or sets the value.
- ///
- public T Value
- {
- get => FromLong(BackingValue);
- set => BackingValue = ToLong(value);
- }
-
- ///
- /// Gets or sets the backing value.
- ///
- protected long BackingValue
- {
- get => Interlocked.Read(ref _backingValue);
- set => Interlocked.Exchange(ref _backingValue, value);
- }
-
- ///
- /// Implements the operator ==.
- ///
- /// a.
- /// The b.
- ///
- /// The result of the operator.
- ///
- public static bool operator ==(AtomicTypeBase a, T b) => a?.Equals(b) == true;
-
- ///
- /// Implements the operator !=.
- ///
- /// a.
- /// The b.
- ///
- /// The result of the operator.
- ///
- public static bool operator !=(AtomicTypeBase a, T b) => a?.Equals(b) == false;
-
- ///
- /// Implements the operator >.
- ///
- /// a.
- /// The b.
- ///
- /// The result of the operator.
- ///
- public static bool operator >(AtomicTypeBase a, T b) => a.CompareTo(b) > 0;
-
- ///
- /// Implements the operator <.
- ///
- /// a.
- /// The b.
- ///
- /// The result of the operator.
- ///
- public static bool operator <(AtomicTypeBase a, T b) => a.CompareTo(b) < 0;
-
- ///
- /// Implements the operator >=.
- ///
- /// a.
- /// The b.
- ///
- /// The result of the operator.
- ///
- public static bool operator >=(AtomicTypeBase a, T b) => a.CompareTo(b) >= 0;
-
- ///
- /// Implements the operator <=.
- ///
- /// a.
- /// The b.
- ///
- /// The result of the operator.
- ///
- public static bool operator <=(AtomicTypeBase a, T b) => a.CompareTo(b) <= 0;
-
- ///
- /// Implements the operator ++.
- ///
- /// The instance.
- ///
- /// The result of the operator.
- ///
- public static AtomicTypeBase operator ++(AtomicTypeBase instance)
- {
- Interlocked.Increment(ref instance._backingValue);
- return instance;
- }
-
- ///
- /// Implements the operator --.
- ///
- /// The instance.
- ///
- /// The result of the operator.
- ///
- public static AtomicTypeBase operator --(AtomicTypeBase instance)
- {
- Interlocked.Decrement(ref instance._backingValue);
- return instance;
- }
-
- ///
- /// Implements the operator -<.
- ///
- /// The instance.
- /// The operand.
- ///
- /// The result of the operator.
- ///
- public static AtomicTypeBase operator +(AtomicTypeBase instance, long operand)
- {
- instance.BackingValue = instance.BackingValue + operand;
- return instance;
- }
-
- ///
- /// Implements the operator -.
- ///
- /// The instance.
- /// The operand.
- ///
- /// The result of the operator.
- ///
- public static AtomicTypeBase operator -(AtomicTypeBase instance, long operand)
- {
- instance.BackingValue = instance.BackingValue - operand;
- return instance;
- }
-
- ///
- /// Compares the value to the other instance.
- ///
- /// The other instance.
- /// 0 if equal, 1 if this instance is greater, -1 if this instance is less than.
- /// When types are incompatible.
- public int CompareTo(object other)
- {
- switch (other)
- {
- case null:
- return 1;
- case AtomicTypeBase atomic:
- return BackingValue.CompareTo(atomic.BackingValue);
- case T variable:
- return Value.CompareTo(variable);
- }
-
- throw new ArgumentException("Incompatible comparison types");
- }
-
- ///
- /// Compares the value to the other instance.
- ///
- /// The other instance.
- /// 0 if equal, 1 if this instance is greater, -1 if this instance is less than.
- public int CompareTo(T other) => Value.CompareTo(other);
-
- ///
- /// Compares the value to the other instance.
- ///
- /// The other instance.
- /// 0 if equal, 1 if this instance is greater, -1 if this instance is less than.
- public int CompareTo(AtomicTypeBase other) => BackingValue.CompareTo(other?.BackingValue ?? default);
-
- ///
- /// Determines whether the specified , is equal to this instance.
- ///
- /// The to compare with this instance.
- ///
- /// true if the specified is equal to this instance; otherwise, false.
- ///
- public override bool Equals(object other)
- {
- switch (other)
- {
- case AtomicTypeBase atomic:
- return Equals(atomic);
- case T variable:
- return Equals(variable);
- }
-
- return false;
- }
-
- ///
- /// Returns a hash code for this instance.
- ///
- ///
- /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
- ///
- public override int GetHashCode() => BackingValue.GetHashCode();
-
- ///
- public bool Equals(AtomicTypeBase other) =>
- BackingValue == (other?.BackingValue ?? default);
-
- ///
- public bool Equals(T other) => Equals(Value, other);
-
- ///
- /// Converts from a long value to the target type.
- ///
- /// The backing value.
- /// The value converted form a long value.
- protected abstract T FromLong(long backingValue);
-
- ///
- /// Converts from the target type to a long value.
- ///
- /// The value.
- /// The value converted to a long value.
- protected abstract long ToLong(T value);
- }
+ /// The initial value.
+ protected AtomicTypeBase(Int64 initialValue) => this.BackingValue = initialValue;
+
+ ///
+ /// Gets or sets the value.
+ ///
+ public T Value {
+ get => this.FromLong(this.BackingValue);
+ set => this.BackingValue = this.ToLong(value);
+ }
+
+ ///
+ /// Gets or sets the backing value.
+ ///
+ protected Int64 BackingValue {
+ get => Interlocked.Read(ref this._backingValue);
+ set => Interlocked.Exchange(ref this._backingValue, value);
+ }
+
+ ///
+ /// Implements the operator ==.
+ ///
+ /// a.
+ /// The b.
+ ///
+ /// The result of the operator.
+ ///
+ public static Boolean operator ==(AtomicTypeBase a, T b) => a?.Equals(b) == true;
+
+ ///
+ /// Implements the operator !=.
+ ///
+ /// a.
+ /// The b.
+ ///
+ /// The result of the operator.
+ ///
+ public static Boolean operator !=(AtomicTypeBase a, T b) => a?.Equals(b) == false;
+
+ ///
+ /// Implements the operator >.
+ ///
+ /// a.
+ /// The b.
+ ///
+ /// The result of the operator.
+ ///
+ public static Boolean operator >(AtomicTypeBase a, T b) => a.CompareTo(b) > 0;
+
+ ///
+ /// Implements the operator <.
+ ///
+ /// a.
+ /// The b.
+ ///
+ /// The result of the operator.
+ ///
+ public static Boolean operator <(AtomicTypeBase a, T b) => a.CompareTo(b) < 0;
+
+ ///
+ /// Implements the operator >=.
+ ///
+ /// a.
+ /// The b.
+ ///
+ /// The result of the operator.
+ ///
+ public static Boolean operator >=(AtomicTypeBase a, T b) => a.CompareTo(b) >= 0;
+
+ ///
+ /// Implements the operator <=.
+ ///
+ /// a.
+ /// The b.
+ ///
+ /// The result of the operator.
+ ///
+ public static Boolean operator <=(AtomicTypeBase a, T b) => a.CompareTo(b) <= 0;
+
+ ///
+ /// Implements the operator ++.
+ ///
+ /// The instance.
+ ///
+ /// The result of the operator.
+ ///
+ public static AtomicTypeBase operator ++(AtomicTypeBase instance) {
+ _ = Interlocked.Increment(ref instance._backingValue);
+ return instance;
+ }
+
+ ///
+ /// Implements the operator --.
+ ///
+ /// The instance.
+ ///
+ /// The result of the operator.
+ ///
+ public static AtomicTypeBase operator --(AtomicTypeBase instance) {
+ _ = Interlocked.Decrement(ref instance._backingValue);
+ return instance;
+ }
+
+ ///
+ /// Implements the operator -<.
+ ///
+ /// The instance.
+ /// The operand.
+ ///
+ /// The result of the operator.
+ ///
+ public static AtomicTypeBase operator +(AtomicTypeBase instance, Int64 operand) {
+ instance.BackingValue += operand;
+ return instance;
+ }
+
+ ///
+ /// Implements the operator -.
+ ///
+ /// The instance.
+ /// The operand.
+ ///
+ /// The result of the operator.
+ ///
+ public static AtomicTypeBase operator -(AtomicTypeBase instance, Int64 operand) {
+ instance.BackingValue -= operand;
+ return instance;
+ }
+
+ ///
+ /// Compares the value to the other instance.
+ ///
+ /// The other instance.
+ /// 0 if equal, 1 if this instance is greater, -1 if this instance is less than.
+ /// When types are incompatible.
+ public Int32 CompareTo(Object other) {
+ switch(other) {
+ case null:
+ return 1;
+ case AtomicTypeBase atomic:
+ return this.BackingValue.CompareTo(atomic.BackingValue);
+ case T variable:
+ return this.Value.CompareTo(variable);
+ }
+
+ throw new ArgumentException("Incompatible comparison types");
+ }
+
+ ///
+ /// Compares the value to the other instance.
+ ///
+ /// The other instance.
+ /// 0 if equal, 1 if this instance is greater, -1 if this instance is less than.
+ public Int32 CompareTo(T other) => this.Value.CompareTo(other);
+
+ ///
+ /// Compares the value to the other instance.
+ ///
+ /// The other instance.
+ /// 0 if equal, 1 if this instance is greater, -1 if this instance is less than.
+ public Int32 CompareTo(AtomicTypeBase other) => this.BackingValue.CompareTo(other?.BackingValue ?? default);
+
+ ///
+ /// Determines whether the specified , is equal to this instance.
+ ///
+ /// The to compare with this instance.
+ ///
+ /// true if the specified is equal to this instance; otherwise, false.
+ ///
+ public override Boolean Equals(Object other) {
+ switch(other) {
+ case AtomicTypeBase atomic:
+ return this.Equals(atomic);
+ case T variable:
+ return this.Equals(variable);
+ }
+
+ return false;
+ }
+
+ ///
+ /// Returns a hash code for this instance.
+ ///
+ ///
+ /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
+ ///
+ public override Int32 GetHashCode() => this.BackingValue.GetHashCode();
+
+ ///
+ public Boolean Equals(AtomicTypeBase other) =>
+ this.BackingValue == (other?.BackingValue ?? default);
+
+ ///
+ public Boolean Equals(T other) => Equals(this.Value, other);
+
+ ///
+ /// Converts from a long value to the target type.
+ ///
+ /// The backing value.
+ /// The value converted form a long value.
+ protected abstract T FromLong(Int64 backingValue);
+
+ ///
+ /// Converts from the target type to a long value.
+ ///
+ /// The value.
+ /// The value converted to a long value.
+ protected abstract Int64 ToLong(T value);
+ }
}
diff --git a/Unosquare.Swan.Lite/Abstractions/ExclusiveTimer.cs b/Unosquare.Swan.Lite/Abstractions/ExclusiveTimer.cs
index 5a01d61..89ad5f0 100644
--- a/Unosquare.Swan.Lite/Abstractions/ExclusiveTimer.cs
+++ b/Unosquare.Swan.Lite/Abstractions/ExclusiveTimer.cs
@@ -1,197 +1,181 @@
-namespace Unosquare.Swan.Abstractions
-{
- using System;
- using System.Threading;
-
+using System;
+using System.Threading;
+
+namespace Unosquare.Swan.Abstractions {
+ ///
+ /// A threading implementation that executes at most one cycle at a time
+ /// in a thread. Callback execution is NOT guaranteed to be carried out
+ /// on the same thread every time the timer fires.
+ ///
+ public sealed class ExclusiveTimer : IDisposable {
+ private readonly Object _syncLock = new Object();
+ private readonly ManualResetEventSlim _cycleDoneEvent = new ManualResetEventSlim(true);
+ private readonly Timer _backingTimer;
+ private readonly TimerCallback _userCallback;
+ private readonly AtomicBoolean _isDisposing = new AtomicBoolean();
+ private readonly AtomicBoolean _isDisposed = new AtomicBoolean();
+ private Int32 _period;
+
///
- /// A threading implementation that executes at most one cycle at a time
- /// in a thread. Callback execution is NOT guaranteed to be carried out
- /// on the same thread every time the timer fires.
+ /// Initializes a new instance of the class.
///
- public sealed class ExclusiveTimer : IDisposable
- {
- private readonly object _syncLock = new object();
- private readonly ManualResetEventSlim _cycleDoneEvent = new ManualResetEventSlim(true);
- private readonly Timer _backingTimer;
- private readonly TimerCallback _userCallback;
- private readonly AtomicBoolean _isDisposing = new AtomicBoolean();
- private readonly AtomicBoolean _isDisposed = new AtomicBoolean();
- private int _period;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The timer callback.
- /// The state.
- /// The due time.
- /// The period.
- public ExclusiveTimer(TimerCallback timerCallback, object state, int dueTime, int period)
- {
- _period = period;
- _userCallback = timerCallback;
- _backingTimer = new Timer(InternalCallback, state ?? this, dueTime, Timeout.Infinite);
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The timer callback.
- /// The state.
- /// The due time.
- /// The period.
- public ExclusiveTimer(TimerCallback timerCallback, object state, TimeSpan dueTime, TimeSpan period)
- : this(timerCallback, state, Convert.ToInt32(dueTime.TotalMilliseconds), Convert.ToInt32(period.TotalMilliseconds))
- {
- // placeholder
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The timer callback.
- public ExclusiveTimer(TimerCallback timerCallback)
- : this(timerCallback, null, Timeout.Infinite, Timeout.Infinite)
- {
- // placholder
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The timer callback.
- /// The due time.
- /// The period.
- public ExclusiveTimer(Action timerCallback, int dueTime, int period)
- : this(s => { timerCallback?.Invoke(); }, null, dueTime, period)
- {
- // placeholder
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The timer callback.
- /// The due time.
- /// The period.
- public ExclusiveTimer(Action timerCallback, TimeSpan dueTime, TimeSpan period)
- : this(s => { timerCallback?.Invoke(); }, null, dueTime, period)
- {
- // placeholder
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The timer callback.
- public ExclusiveTimer(Action timerCallback)
- : this(timerCallback, Timeout.Infinite, Timeout.Infinite)
- {
- // placeholder
- }
-
- ///
- /// Gets a value indicating whether this instance is disposing.
- ///
- ///
- /// true if this instance is disposing; otherwise, false.
- ///
- public bool IsDisposing => _isDisposing.Value;
-
- ///
- /// Gets a value indicating whether this instance is disposed.
- ///
- ///
- /// true if this instance is disposed; otherwise, false.
- ///
- public bool IsDisposed => _isDisposed.Value;
-
- ///
- /// Changes the start time and the interval between method invocations for the internal timer.
- ///
- /// The due time.
- /// The period.
- public void Change(int dueTime, int period)
- {
- _period = period;
-
- _backingTimer.Change(dueTime, Timeout.Infinite);
- }
-
- ///
- /// Changes the start time and the interval between method invocations for the internal timer.
- ///
- /// The due time.
- /// The period.
- public void Change(TimeSpan dueTime, TimeSpan period)
- => Change(Convert.ToInt32(dueTime.TotalMilliseconds), Convert.ToInt32(period.TotalMilliseconds));
-
- ///
- /// Changes the interval between method invocations for the internal timer.
- ///
- /// The period.
- public void Resume(int period) => Change(0, period);
-
- ///
- /// Changes the interval between method invocations for the internal timer.
- ///
- /// The period.
- public void Resume(TimeSpan period) => Change(TimeSpan.Zero, period);
-
- ///
- /// Pauses this instance.
- ///
- public void Pause() => Change(Timeout.Infinite, Timeout.Infinite);
-
- ///
- public void Dispose()
- {
- lock (_syncLock)
- {
- if (_isDisposed == true || _isDisposing == true)
- return;
-
- _isDisposing.Value = true;
- }
-
- try
- {
- _backingTimer.Dispose();
- _cycleDoneEvent.Wait();
- _cycleDoneEvent.Dispose();
- }
- finally
- {
- _isDisposed.Value = true;
- _isDisposing.Value = false;
- }
- }
-
- ///
- /// Logic that runs every time the timer hits the due time.
- ///
- /// The state.
- private void InternalCallback(object state)
- {
- lock (_syncLock)
- {
- if (IsDisposed || IsDisposing)
- return;
- }
-
- if (_cycleDoneEvent.IsSet == false)
- return;
-
- _cycleDoneEvent.Reset();
-
- try
- {
- _userCallback(state);
- }
- finally
- {
- _cycleDoneEvent?.Set();
- _backingTimer?.Change(_period, Timeout.Infinite);
- }
- }
- }
+ /// The timer callback.
+ /// The state.
+ /// The due time.
+ /// The period.
+ public ExclusiveTimer(TimerCallback timerCallback, Object state, Int32 dueTime, Int32 period) {
+ this._period = period;
+ this._userCallback = timerCallback;
+ this._backingTimer = new Timer(this.InternalCallback, state ?? this, dueTime, Timeout.Infinite);
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The timer callback.
+ /// The state.
+ /// The due time.
+ /// The period.
+ public ExclusiveTimer(TimerCallback timerCallback, Object state, TimeSpan dueTime, TimeSpan period)
+ : this(timerCallback, state, Convert.ToInt32(dueTime.TotalMilliseconds), Convert.ToInt32(period.TotalMilliseconds)) {
+ // placeholder
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The timer callback.
+ public ExclusiveTimer(TimerCallback timerCallback)
+ : this(timerCallback, null, Timeout.Infinite, Timeout.Infinite) {
+ // placholder
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The timer callback.
+ /// The due time.
+ /// The period.
+ public ExclusiveTimer(Action timerCallback, Int32 dueTime, Int32 period)
+ : this(s => timerCallback?.Invoke(), null, dueTime, period) {
+ // placeholder
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The timer callback.
+ /// The due time.
+ /// The period.
+ public ExclusiveTimer(Action timerCallback, TimeSpan dueTime, TimeSpan period)
+ : this(s => timerCallback?.Invoke(), null, dueTime, period) {
+ // placeholder
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The timer callback.
+ public ExclusiveTimer(Action timerCallback)
+ : this(timerCallback, Timeout.Infinite, Timeout.Infinite) {
+ // placeholder
+ }
+
+ ///
+ /// Gets a value indicating whether this instance is disposing.
+ ///
+ ///
+ /// true if this instance is disposing; otherwise, false.
+ ///
+ public Boolean IsDisposing => this._isDisposing.Value;
+
+ ///
+ /// Gets a value indicating whether this instance is disposed.
+ ///
+ ///
+ /// true if this instance is disposed; otherwise, false.
+ ///
+ public Boolean IsDisposed => this._isDisposed.Value;
+
+ ///
+ /// Changes the start time and the interval between method invocations for the internal timer.
+ ///
+ /// The due time.
+ /// The period.
+ public void Change(Int32 dueTime, Int32 period) {
+ this._period = period;
+
+ _ = this._backingTimer.Change(dueTime, Timeout.Infinite);
+ }
+
+ ///
+ /// Changes the start time and the interval between method invocations for the internal timer.
+ ///
+ /// The due time.
+ /// The period.
+ public void Change(TimeSpan dueTime, TimeSpan period)
+ => this.Change(Convert.ToInt32(dueTime.TotalMilliseconds), Convert.ToInt32(period.TotalMilliseconds));
+
+ ///
+ /// Changes the interval between method invocations for the internal timer.
+ ///
+ /// The period.
+ public void Resume(Int32 period) => this.Change(0, period);
+
+ ///
+ /// Changes the interval between method invocations for the internal timer.
+ ///
+ /// The period.
+ public void Resume(TimeSpan period) => this.Change(TimeSpan.Zero, period);
+
+ ///
+ /// Pauses this instance.
+ ///
+ public void Pause() => this.Change(Timeout.Infinite, Timeout.Infinite);
+
+ ///
+ public void Dispose() {
+ lock(this._syncLock) {
+ if(this._isDisposed == true || this._isDisposing == true) {
+ return;
+ }
+
+ this._isDisposing.Value = true;
+ }
+
+ try {
+ this._backingTimer.Dispose();
+ this._cycleDoneEvent.Wait();
+ this._cycleDoneEvent.Dispose();
+ } finally {
+ this._isDisposed.Value = true;
+ this._isDisposing.Value = false;
+ }
+ }
+
+ ///
+ /// Logic that runs every time the timer hits the due time.
+ ///
+ /// The state.
+ private void InternalCallback(Object state) {
+ lock(this._syncLock) {
+ if(this.IsDisposed || this.IsDisposing) {
+ return;
+ }
+ }
+
+ if(this._cycleDoneEvent.IsSet == false) {
+ return;
+ }
+
+ this._cycleDoneEvent.Reset();
+
+ try {
+ this._userCallback(state);
+ } finally {
+ this._cycleDoneEvent?.Set();
+ _ = this._backingTimer?.Change(this._period, Timeout.Infinite);
+ }
+ }
+ }
}
diff --git a/Unosquare.Swan.Lite/Abstractions/ExpressionParser.cs b/Unosquare.Swan.Lite/Abstractions/ExpressionParser.cs
index 85890f8..2816e51 100644
--- a/Unosquare.Swan.Lite/Abstractions/ExpressionParser.cs
+++ b/Unosquare.Swan.Lite/Abstractions/ExpressionParser.cs
@@ -1,94 +1,88 @@
-namespace Unosquare.Swan.Abstractions
-{
- using System;
- using System.Linq;
- using System.Collections.Generic;
- using System.Linq.Expressions;
-
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+namespace Unosquare.Swan.Abstractions {
+ ///
+ /// Represents a generic expression parser.
+ ///
+ public abstract class ExpressionParser {
///
- /// Represents a generic expression parser.
+ /// Resolves the expression.
///
- public abstract class ExpressionParser
- {
- ///
- /// Resolves the expression.
- ///
- /// The type of expression result.
- /// The tokens.
- /// The representation of the expression parsed.
- public virtual T ResolveExpression(IEnumerable tokens)
- {
- var conversion = Expression.Convert(Parse(tokens), typeof(T));
- return Expression.Lambda>(conversion).Compile()();
- }
-
- ///
- /// Parses the specified tokens.
- ///
- /// The tokens.
- /// The final expression.
- public virtual Expression Parse(IEnumerable tokens)
- {
- var expressionStack = new List>();
-
- foreach (var token in tokens)
- {
- if (expressionStack.Any() == false)
- expressionStack.Add(new Stack());
-
- switch (token.Type)
- {
- case TokenType.Wall:
- expressionStack.Add(new Stack());
- break;
- case TokenType.Number:
- expressionStack.Last().Push(Expression.Constant(Convert.ToDecimal(token.Value)));
- break;
- case TokenType.Variable:
- ResolveVariable(token.Value, expressionStack.Last());
- break;
- case TokenType.String:
- expressionStack.Last().Push(Expression.Constant(token.Value));
- break;
- case TokenType.Operator:
- ResolveOperator(token.Value, expressionStack.Last());
- break;
- case TokenType.Function:
- ResolveFunction(token.Value, expressionStack.Last());
-
- if (expressionStack.Count > 1 && expressionStack.Last().Count == 1)
- {
- var lastValue = expressionStack.Last().Pop();
- expressionStack.Remove(expressionStack.Last());
- expressionStack.Last().Push(lastValue);
- }
-
- break;
- }
- }
-
- return expressionStack.Last().Pop();
- }
-
- ///
- /// Resolves the variable.
- ///
- /// The value.
- /// The expression stack.
- public abstract void ResolveVariable(string value, Stack expressionStack);
-
- ///
- /// Resolves the operator.
- ///
- /// The value.
- /// The expression stack.
- public abstract void ResolveOperator(string value, Stack expressionStack);
-
- ///
- /// Resolves the function.
- ///
- /// The value.
- /// The expression stack.
- public abstract void ResolveFunction(string value, Stack expressionStack);
- }
+ /// The type of expression result.
+ /// The tokens.
+ /// The representation of the expression parsed.
+ public virtual T ResolveExpression(IEnumerable tokens) {
+ UnaryExpression conversion = Expression.Convert(this.Parse(tokens), typeof(T));
+ return Expression.Lambda>(conversion).Compile()();
+ }
+
+ ///
+ /// Parses the specified tokens.
+ ///
+ /// The tokens.
+ /// The final expression.
+ public virtual Expression Parse(IEnumerable tokens) {
+ List> expressionStack = new List>();
+
+ foreach(Token token in tokens) {
+ if(expressionStack.Any() == false) {
+ expressionStack.Add(new Stack());
+ }
+
+ switch(token.Type) {
+ case TokenType.Wall:
+ expressionStack.Add(new Stack());
+ break;
+ case TokenType.Number:
+ expressionStack.Last().Push(Expression.Constant(Convert.ToDecimal(token.Value)));
+ break;
+ case TokenType.Variable:
+ this.ResolveVariable(token.Value, expressionStack.Last());
+ break;
+ case TokenType.String:
+ expressionStack.Last().Push(Expression.Constant(token.Value));
+ break;
+ case TokenType.Operator:
+ this.ResolveOperator(token.Value, expressionStack.Last());
+ break;
+ case TokenType.Function:
+ this.ResolveFunction(token.Value, expressionStack.Last());
+
+ if(expressionStack.Count > 1 && expressionStack.Last().Count == 1) {
+ Expression lastValue = expressionStack.Last().Pop();
+ _ = expressionStack.Remove(expressionStack.Last());
+ expressionStack.Last().Push(lastValue);
+ }
+
+ break;
+ }
+ }
+
+ return expressionStack.Last().Pop();
+ }
+
+ ///
+ /// Resolves the variable.
+ ///
+ /// The value.
+ /// The expression stack.
+ public abstract void ResolveVariable(String value, Stack expressionStack);
+
+ ///
+ /// Resolves the operator.
+ ///
+ /// The value.
+ /// The expression stack.
+ public abstract void ResolveOperator(String value, Stack expressionStack);
+
+ ///
+ /// Resolves the function.
+ ///
+ /// The value.
+ /// The expression stack.
+ public abstract void ResolveFunction(String value, Stack expressionStack);
+ }
}
diff --git a/Unosquare.Swan.Lite/Abstractions/IObjectMap.cs b/Unosquare.Swan.Lite/Abstractions/IObjectMap.cs
index 1c0419e..49732a4 100644
--- a/Unosquare.Swan.Lite/Abstractions/IObjectMap.cs
+++ b/Unosquare.Swan.Lite/Abstractions/IObjectMap.cs
@@ -1,27 +1,31 @@
-namespace Unosquare.Swan.Abstractions
-{
- using System;
- using System.Collections.Generic;
- using System.Reflection;
-
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace Unosquare.Swan.Abstractions {
+ ///
+ /// Interface object map.
+ ///
+ public interface IObjectMap {
///
- /// Interface object map.
+ /// Gets or sets the map.
///
- public interface IObjectMap
- {
- ///
- /// Gets or sets the map.
- ///
- Dictionary> Map { get; }
-
- ///
- /// Gets or sets the type of the source.
- ///
- Type SourceType { get; }
-
- ///
- /// Gets or sets the type of the destination.
- ///
- Type DestinationType { get; }
- }
+ Dictionary> Map {
+ get;
+ }
+
+ ///
+ /// Gets or sets the type of the source.
+ ///
+ Type SourceType {
+ get;
+ }
+
+ ///
+ /// Gets or sets the type of the destination.
+ ///
+ Type DestinationType {
+ get;
+ }
+ }
}
diff --git a/Unosquare.Swan.Lite/Abstractions/ISyncLocker.cs b/Unosquare.Swan.Lite/Abstractions/ISyncLocker.cs
index 30a8b39..bcf1cb4 100644
--- a/Unosquare.Swan.Lite/Abstractions/ISyncLocker.cs
+++ b/Unosquare.Swan.Lite/Abstractions/ISyncLocker.cs
@@ -1,24 +1,22 @@
-namespace Unosquare.Swan.Abstractions
-{
- using System;
-
+using System;
+
+namespace Unosquare.Swan.Abstractions {
+ ///
+ /// Defines a generic interface for synchronized locking mechanisms.
+ ///
+ public interface ISyncLocker : IDisposable {
///
- /// Defines a generic interface for synchronized locking mechanisms.
+ /// Acquires a writer lock.
+ /// The lock is released when the returned locking object is disposed.
///
- public interface ISyncLocker : IDisposable
- {
- ///
- /// Acquires a writer lock.
- /// The lock is released when the returned locking object is disposed.
- ///
- /// A disposable locking object.
- IDisposable AcquireWriterLock();
-
- ///
- /// Acquires a reader lock.
- /// The lock is released when the returned locking object is disposed.
- ///
- /// A disposable locking object.
- IDisposable AcquireReaderLock();
- }
+ /// A disposable locking object.
+ IDisposable AcquireWriterLock();
+
+ ///
+ /// Acquires a reader lock.
+ /// The lock is released when the returned locking object is disposed.
+ ///
+ /// A disposable locking object.
+ IDisposable AcquireReaderLock();
+ }
}
diff --git a/Unosquare.Swan.Lite/Abstractions/IValidator.cs b/Unosquare.Swan.Lite/Abstractions/IValidator.cs
index b8aec9d..3ec35f0 100644
--- a/Unosquare.Swan.Lite/Abstractions/IValidator.cs
+++ b/Unosquare.Swan.Lite/Abstractions/IValidator.cs
@@ -1,21 +1,23 @@
-namespace Unosquare.Swan.Abstractions
-{
+using System;
+
+namespace Unosquare.Swan.Abstractions {
+ ///
+ /// A simple Validator interface.
+ ///
+ public interface IValidator {
///
- /// A simple Validator interface.
+ /// The error message.
///
- public interface IValidator
- {
- ///
- /// The error message.
- ///
- string ErrorMessage { get; }
-
- ///
- /// Checks if a value is valid.
- ///
- /// The type.
- /// The value.
- /// True if it is valid.False if it is not.
- bool IsValid(T value);
- }
+ String ErrorMessage {
+ get;
+ }
+
+ ///
+ /// Checks if a value is valid.
+ ///
+ /// The type.
+ /// The value.
+ /// True if it is valid.False if it is not.
+ Boolean IsValid(T value);
+ }
}
\ No newline at end of file
diff --git a/Unosquare.Swan.Lite/Abstractions/IWaitEvent.cs b/Unosquare.Swan.Lite/Abstractions/IWaitEvent.cs
index 39758ff..dd17d43 100644
--- a/Unosquare.Swan.Lite/Abstractions/IWaitEvent.cs
+++ b/Unosquare.Swan.Lite/Abstractions/IWaitEvent.cs
@@ -1,57 +1,63 @@
-namespace Unosquare.Swan.Abstractions
-{
- using System;
-
+using System;
+
+namespace Unosquare.Swan.Abstractions {
+ ///
+ /// Provides a generalized API for ManualResetEvent and ManualResetEventSlim.
+ ///
+ ///
+ public interface IWaitEvent : IDisposable {
///
- /// Provides a generalized API for ManualResetEvent and ManualResetEventSlim.
+ /// Gets a value indicating whether the event is in the completed state.
///
- ///
- public interface IWaitEvent : IDisposable
- {
- ///
- /// Gets a value indicating whether the event is in the completed state.
- ///
- bool IsCompleted { get; }
-
- ///
- /// Gets a value indicating whether the Begin method has been called.
- /// It returns false after the Complete method is called.
- ///
- bool IsInProgress { get; }
-
- ///
- /// Returns true if the underlying handle is not closed and it is still valid.
- ///
- bool IsValid { get; }
-
- ///
- /// Gets a value indicating whether this instance is disposed.
- ///
- bool IsDisposed { get; }
-
- ///
- /// Enters the state in which waiters need to wait.
- /// All future waiters will block when they call the Wait method.
- ///
- void Begin();
-
- ///
- /// Leaves the state in which waiters need to wait.
- /// All current waiters will continue.
- ///
- void Complete();
-
- ///
- /// Waits for the event to be completed.
- ///
- void Wait();
-
- ///
- /// Waits for the event to be completed.
- /// Returns true when there was no timeout. False if the timeout was reached.
- ///
- /// The maximum amount of time to wait for.
- /// true when there was no timeout. false if the timeout was reached.
- bool Wait(TimeSpan timeout);
- }
+ Boolean IsCompleted {
+ get;
+ }
+
+ ///
+ /// Gets a value indicating whether the Begin method has been called.
+ /// It returns false after the Complete method is called.
+ ///
+ Boolean IsInProgress {
+ get;
+ }
+
+ ///
+ /// Returns true if the underlying handle is not closed and it is still valid.
+ ///
+ Boolean IsValid {
+ get;
+ }
+
+ ///
+ /// Gets a value indicating whether this instance is disposed.
+ ///
+ Boolean IsDisposed {
+ get;
+ }
+
+ ///
+ /// Enters the state in which waiters need to wait.
+ /// All future waiters will block when they call the Wait method.
+ ///
+ void Begin();
+
+ ///
+ /// Leaves the state in which waiters need to wait.
+ /// All current waiters will continue.
+ ///
+ void Complete();
+
+ ///
+ /// Waits for the event to be completed.
+ ///
+ void Wait();
+
+ ///
+ /// Waits for the event to be completed.
+ /// Returns true when there was no timeout. False if the timeout was reached.
+ ///
+ /// The maximum amount of time to wait for.
+ /// true when there was no timeout. false if the timeout was reached.
+ Boolean Wait(TimeSpan timeout);
+ }
}
diff --git a/Unosquare.Swan.Lite/Abstractions/IWorker.cs b/Unosquare.Swan.Lite/Abstractions/IWorker.cs
index 2efe9f5..ad3b114 100644
--- a/Unosquare.Swan.Lite/Abstractions/IWorker.cs
+++ b/Unosquare.Swan.Lite/Abstractions/IWorker.cs
@@ -1,18 +1,16 @@
-namespace Unosquare.Swan.Abstractions
-{
+namespace Unosquare.Swan.Abstractions {
+ ///
+ /// A simple interface for application workers.
+ ///
+ public interface IWorker {
///
- /// A simple interface for application workers.
+ /// Should start the task immediately and asynchronously.
///
- public interface IWorker
- {
- ///
- /// Should start the task immediately and asynchronously.
- ///
- void Start();
-
- ///
- /// Should stop the task immediately and synchronously.
- ///
- void Stop();
- }
+ void Start();
+
+ ///
+ /// Should stop the task immediately and synchronously.
+ ///
+ void Stop();
+ }
}
diff --git a/Unosquare.Swan.Lite/Abstractions/RunnerBase.cs b/Unosquare.Swan.Lite/Abstractions/RunnerBase.cs
index cd5f6b8..93fb86c 100644
--- a/Unosquare.Swan.Lite/Abstractions/RunnerBase.cs
+++ b/Unosquare.Swan.Lite/Abstractions/RunnerBase.cs
@@ -1,169 +1,155 @@
#if !NETSTANDARD1_3
-namespace Unosquare.Swan.Abstractions
-{
- using System;
- using System.Collections.Generic;
- using System.Threading;
- using Swan;
-
+using System;
+using System.Collections.Generic;
+using System.Threading;
+namespace Unosquare.Swan.Abstractions {
+ ///
+ /// Represents an background worker abstraction with a life cycle and running at a independent thread.
+ ///
+ public abstract class RunnerBase {
+ private Thread _worker;
+ private CancellationTokenSource _cancelTokenSource;
+ private ManualResetEvent _workFinished;
+
///
- /// Represents an background worker abstraction with a life cycle and running at a independent thread.
+ /// Initializes a new instance of the class.
///
- public abstract class RunnerBase
- {
- private Thread _worker;
- private CancellationTokenSource _cancelTokenSource;
- private ManualResetEvent _workFinished;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// if set to true [is enabled].
- protected RunnerBase(bool isEnabled)
- {
- Name = GetType().Name;
- IsEnabled = isEnabled;
- }
-
- ///
- /// Gets the error messages.
- ///
- ///
- /// The error messages.
- ///
- public List ErrorMessages { get; } = new List();
-
- ///
- /// Gets the name.
- ///
- ///
- /// The name.
- ///
- public string Name { get; }
-
- ///
- /// Gets a value indicating whether this instance is running.
- ///
- ///
- /// true if this instance is running; otherwise, false.
- ///
- public bool IsRunning { get; private set; }
-
- ///
- /// Gets a value indicating whether this instance is enabled.
- ///
- ///
- /// true if this instance is enabled; otherwise, false.
- ///
- public bool IsEnabled { get; }
-
- ///
- /// Starts this instance.
- ///
- public virtual void Start()
- {
- if (IsEnabled == false)
- return;
-
- $"Start Requested".Debug(Name);
- _cancelTokenSource = new CancellationTokenSource();
- _workFinished = new ManualResetEvent(false);
-
- _worker = new Thread(() =>
- {
- _workFinished.Reset();
- IsRunning = true;
- try
- {
- Setup();
- DoBackgroundWork(_cancelTokenSource.Token);
- }
- catch (ThreadAbortException)
- {
- $"{nameof(ThreadAbortException)} caught.".Warn(Name);
- }
- catch (Exception ex)
- {
- $"{ex.GetType()}: {ex.Message}\r\n{ex.StackTrace}".Error(Name);
- }
- finally
- {
- Cleanup();
- _workFinished?.Set();
- IsRunning = false;
- "Stopped Completely".Debug(Name);
- }
- })
- {
- IsBackground = true,
- Name = $"{Name}Thread",
- };
-
- _worker.Start();
- }
-
- ///
- /// Stops this instance.
- ///
- public virtual void Stop()
- {
- if (IsEnabled == false || IsRunning == false)
- return;
-
- $"Stop Requested".Debug(Name);
- _cancelTokenSource.Cancel();
- var waitRetries = 5;
- while (waitRetries >= 1)
- {
- if (_workFinished.WaitOne(250))
- {
- waitRetries = -1;
- break;
- }
-
- waitRetries--;
- }
-
- if (waitRetries < 0)
- {
- "Workbench stopped gracefully".Debug(Name);
- }
- else
- {
- "Did not respond to stop request. Aborting thread and waiting . . .".Warn(Name);
- _worker.Abort();
-
- if (_workFinished.WaitOne(5000) == false)
- "Waited and no response. Worker might have been left in an inconsistent state.".Error(Name);
- else
- "Waited for worker and it finally responded (OK).".Debug(Name);
- }
-
- _workFinished.Dispose();
- _workFinished = null;
- }
-
- ///
- /// Setups this instance.
- ///
- protected virtual void Setup()
- {
- // empty
- }
-
- ///
- /// Cleanups this instance.
- ///
- protected virtual void Cleanup()
- {
- // empty
- }
-
- ///
- /// Does the background work.
- ///
- /// The ct.
- protected abstract void DoBackgroundWork(CancellationToken ct);
- }
+ /// if set to true [is enabled].
+ protected RunnerBase(Boolean isEnabled) {
+ this.Name = this.GetType().Name;
+ this.IsEnabled = isEnabled;
+ }
+
+ ///
+ /// Gets the error messages.
+ ///
+ ///
+ /// The error messages.
+ ///
+ public List ErrorMessages { get; } = new List();
+
+ ///
+ /// Gets the name.
+ ///
+ ///
+ /// The name.
+ ///
+ public String Name {
+ get;
+ }
+
+ ///
+ /// Gets a value indicating whether this instance is running.
+ ///
+ ///
+ /// true if this instance is running; otherwise, false.
+ ///
+ public Boolean IsRunning {
+ get; private set;
+ }
+
+ ///
+ /// Gets a value indicating whether this instance is enabled.
+ ///
+ ///
+ /// true if this instance is enabled; otherwise, false.
+ ///
+ public Boolean IsEnabled {
+ get;
+ }
+
+ ///
+ /// Starts this instance.
+ ///
+ public virtual void Start() {
+ if(this.IsEnabled == false) {
+ return;
+ }
+
+ $"Start Requested".Debug(this.Name);
+ this._cancelTokenSource = new CancellationTokenSource();
+ this._workFinished = new ManualResetEvent(false);
+
+ this._worker = new Thread(() => {
+ _ = this._workFinished.Reset();
+ this.IsRunning = true;
+ try {
+ this.Setup();
+ this.DoBackgroundWork(this._cancelTokenSource.Token);
+ } catch(ThreadAbortException) {
+ $"{nameof(ThreadAbortException)} caught.".Warn(this.Name);
+ } catch(Exception ex) {
+ $"{ex.GetType()}: {ex.Message}\r\n{ex.StackTrace}".Error(this.Name);
+ } finally {
+ this.Cleanup();
+ _ = this._workFinished?.Set();
+ this.IsRunning = false;
+ "Stopped Completely".Debug(this.Name);
+ }
+ }) {
+ IsBackground = true,
+ Name = $"{this.Name}Thread",
+ };
+
+ this._worker.Start();
+ }
+
+ ///
+ /// Stops this instance.
+ ///
+ public virtual void Stop() {
+ if(this.IsEnabled == false || this.IsRunning == false) {
+ return;
+ }
+
+ $"Stop Requested".Debug(this.Name);
+ this._cancelTokenSource.Cancel();
+ Int32 waitRetries = 5;
+ while(waitRetries >= 1) {
+ if(this._workFinished.WaitOne(250)) {
+ waitRetries = -1;
+ break;
+ }
+
+ waitRetries--;
+ }
+
+ if(waitRetries < 0) {
+ "Workbench stopped gracefully".Debug(this.Name);
+ } else {
+ "Did not respond to stop request. Aborting thread and waiting . . .".Warn(this.Name);
+ this._worker.Abort();
+
+ if(this._workFinished.WaitOne(5000) == false) {
+ "Waited and no response. Worker might have been left in an inconsistent state.".Error(this.Name);
+ } else {
+ "Waited for worker and it finally responded (OK).".Debug(this.Name);
+ }
+ }
+
+ this._workFinished.Dispose();
+ this._workFinished = null;
+ }
+
+ ///
+ /// Setups this instance.
+ ///
+ protected virtual void Setup() {
+ // empty
+ }
+
+ ///
+ /// Cleanups this instance.
+ ///
+ protected virtual void Cleanup() {
+ // empty
+ }
+
+ ///
+ /// Does the background work.
+ ///
+ /// The ct.
+ protected abstract void DoBackgroundWork(CancellationToken ct);
+ }
}
#endif
\ No newline at end of file
diff --git a/Unosquare.Swan.Lite/Abstractions/SettingsProvider.cs b/Unosquare.Swan.Lite/Abstractions/SettingsProvider.cs
index a13ed28..c134829 100644
--- a/Unosquare.Swan.Lite/Abstractions/SettingsProvider.cs
+++ b/Unosquare.Swan.Lite/Abstractions/SettingsProvider.cs
@@ -1,188 +1,184 @@
-namespace Unosquare.Swan.Abstractions
-{
- using Formatters;
- using Reflection;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Reflection;
-
+using Unosquare.Swan.Formatters;
+using Unosquare.Swan.Reflection;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+namespace Unosquare.Swan.Abstractions {
+ ///
+ /// Represents a provider to save and load settings using a plain JSON file.
+ ///
+ ///
+ /// The following example shows how to save and load settings.
+ ///
+ /// using Unosquare.Swan.Abstractions;
+ ///
+ /// public class Example
+ /// {
+ /// public static void Main()
+ /// {
+ /// // get user from settings
+ /// var user = SettingsProvider<Settings>.Instance.Global.User;
+ ///
+ /// // modify the port
+ /// SettingsProvider<Settings>.Instance.Global.Port = 20;
+ ///
+ /// // if we want these settings to persist
+ /// SettingsProvider<Settings>.Instance.PersistGlobalSettings();
+ /// }
+ ///
+ /// public class Settings
+ /// {
+ /// public int Port { get; set; } = 9696;
+ ///
+ /// public string User { get; set; } = "User";
+ /// }
+ /// }
+ ///
+ ///
+ /// The type of settings model.
+ public sealed class SettingsProvider
+ : SingletonBase> {
+ private readonly Object _syncRoot = new Object();
+
+ private T _global;
+
///
- /// Represents a provider to save and load settings using a plain JSON file.
+ /// Gets or sets the configuration file path. By default the entry assembly directory is used
+ /// and the filename is 'appsettings.json'.
///
- ///
- /// The following example shows how to save and load settings.
- ///
- /// using Unosquare.Swan.Abstractions;
- ///
- /// public class Example
- /// {
- /// public static void Main()
- /// {
- /// // get user from settings
- /// var user = SettingsProvider<Settings>.Instance.Global.User;
- ///
- /// // modify the port
- /// SettingsProvider<Settings>.Instance.Global.Port = 20;
- ///
- /// // if we want these settings to persist
- /// SettingsProvider<Settings>.Instance.PersistGlobalSettings();
- /// }
- ///
- /// public class Settings
- /// {
- /// public int Port { get; set; } = 9696;
- ///
- /// public string User { get; set; } = "User";
- /// }
- /// }
- ///
- ///
- /// The type of settings model.
- public sealed class SettingsProvider
- : SingletonBase>
- {
- private readonly object _syncRoot = new object();
-
- private T _global;
-
- ///
- /// Gets or sets the configuration file path. By default the entry assembly directory is used
- /// and the filename is 'appsettings.json'.
- ///
- ///
- /// The configuration file path.
- ///
- public string ConfigurationFilePath { get; set; } =
+ ///
+ /// The configuration file path.
+ ///
+ public String ConfigurationFilePath {
+ get; set;
+ } =
#if NETSTANDARD1_3
Path.Combine(Runtime.LocalStoragePath, "appsettings.json");
#else
- Path.Combine(Runtime.EntryAssemblyDirectory, "appsettings.json");
+ Path.Combine(Runtime.EntryAssemblyDirectory, "appsettings.json");
#endif
-
- ///
- /// Gets the global settings object.
- ///
- ///
- /// The global settings object.
- ///
- public T Global
- {
- get
- {
- lock (_syncRoot)
- {
- if (Equals(_global, default(T)))
- ReloadGlobalSettings();
-
- return _global;
- }
- }
- }
-
- ///
- /// Reloads the global settings.
- ///
- public void ReloadGlobalSettings()
- {
- if (File.Exists(ConfigurationFilePath) == false || File.ReadAllText(ConfigurationFilePath).Length == 0)
- {
- ResetGlobalSettings();
- return;
- }
-
- lock (_syncRoot)
- _global = Json.Deserialize(File.ReadAllText(ConfigurationFilePath));
- }
-
- ///
- /// Persists the global settings.
- ///
- public void PersistGlobalSettings() => File.WriteAllText(ConfigurationFilePath, Json.Serialize(Global, true));
-
- ///
- /// Updates settings from list.
- ///
- /// The list.
- ///
- /// A list of settings of type ref="ExtendedPropertyInfo".
- ///
- /// propertyList.
- public List RefreshFromList(List> propertyList)
- {
- if (propertyList == null)
- throw new ArgumentNullException(nameof(propertyList));
-
- var changedSettings = new List();
- var globalProps = Runtime.PropertyTypeCache.RetrieveAllProperties();
-
- foreach (var property in propertyList)
- {
- var propertyInfo = globalProps.FirstOrDefault(x => x.Name == property.Property);
-
- if (propertyInfo == null) continue;
-
- var originalValue = propertyInfo.GetValue(Global);
- var isChanged = propertyInfo.PropertyType.IsArray
- ? property.Value is IEnumerable enumerable && propertyInfo.TrySetArray(enumerable.Cast