Skip to content

Commit

Permalink
Added extension methods for making collections observable.
Browse files Browse the repository at this point in the history
References #9.
  • Loading branch information
jspuij committed Nov 26, 2019
1 parent 126eba5 commit 30ff35e
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/Cortex.Net.Fody/EnumerableInterfaceWeaver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private void ReassignEnumerable(PropertyDefinition propertyDefinition, TypeRefer
var module = propertyDefinition.Module;
var declaringType = propertyDefinition.DeclaringType;
var importedType = observableEnumerableType;
var genricConstructor = importedType.Resolve().Methods.Single(x => x.IsConstructor && !x.IsStatic);
var genricConstructor = importedType.Resolve().Methods.Where(x => x.IsConstructor && !x.IsStatic).OrderBy(x => x.Parameters.Count).First();
MethodReference constructorReference;

// property name
Expand Down
119 changes: 119 additions & 0 deletions src/Cortex.Net/Api/SharedStateObservableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ namespace Cortex.Net.Api
using System;
using System.Collections.Generic;
using System.Text;
using Cortex.Net.Core;
using Cortex.Net.Types;

/// <summary>
/// Extension methods for ISharedState to make attach an object to a shared state and make sure that
Expand Down Expand Up @@ -62,5 +64,122 @@ public static T Observable<T>(this ISharedState sharedState, Func<T> initializer
SharedState.SetAsyncLocalState(null);
}
}

/// <summary>
/// Boxes the value T inside an <see cref="IObservableValue{T}" /> instance.
/// </summary>
/// <typeparam name="T">The type to box.</typeparam>
/// <param name="sharedState">The shared state to operate on.</param>
/// <param name="initialValue">The initial value to use.</param>
/// <param name="name">The name of the observable value.</param>
/// <param name="enhancer">The optional enhancer to use. default enhancer is the referenceEnhancer.</param>
/// <returns>The observable.</returns>
public static IObservableValue<T> Box<T>(this ISharedState sharedState, T initialValue, string name = null, IEnhancer enhancer = null)
{
if (sharedState is null)
{
throw new ArgumentNullException(nameof(sharedState));
}

if (enhancer is null)
{
enhancer = sharedState.ReferenceEnhancer();
}

if (string.IsNullOrEmpty(name))
{
name = $"{nameof(ObservableValue<T>)}@{sharedState.GetUniqueId()}";
}

return new ObservableValue<T>(sharedState, name, enhancer, initialValue);
}

/// <summary>
/// Creates an observable Collection from an IEnumerable.
/// </summary>
/// <typeparam name="T">The type of the elements.</typeparam>
/// <param name="sharedState">The shared state to operate on.</param>
/// <param name="initialValues">The initial values to use.</param>
/// <param name="name">The name of the observable collection.</param>
/// <param name="enhancer">The optional enhancer to use. default enhancer is the deep enhancer.</param>
/// <returns>The observable.</returns>
public static ICollection<T> Collection<T>(this ISharedState sharedState, IEnumerable<T> initialValues = null, string name = null, IEnhancer enhancer = null)
{
if (sharedState is null)
{
throw new ArgumentNullException(nameof(sharedState));
}

if (enhancer is null)
{
enhancer = sharedState.DeepEnhancer();
}

if (string.IsNullOrEmpty(name))
{
name = $"{nameof(ObservableCollection<T>)}@{sharedState.GetUniqueId()}";
}

return new ObservableCollection<T>(sharedState, enhancer, initialValues, name);
}

/// <summary>
/// Creates an observable Set from an initial Ienumberable.
/// </summary>
/// <typeparam name="T">The type of the elements.</typeparam>
/// <param name="sharedState">The shared state to operate on.</param>
/// <param name="initialValues">The initial values to use.</param>
/// <param name="name">The name of the observable collection.</param>
/// <param name="enhancer">The optional enhancer to use. default enhancer is the deep enhancer.</param>
/// <returns>The observable.</returns>
public static ISet<T> Set<T>(this ISharedState sharedState, IEnumerable<T> initialValues = null, string name = null, IEnhancer enhancer = null)
{
if (sharedState is null)
{
throw new ArgumentNullException(nameof(sharedState));
}

if (enhancer is null)
{
enhancer = sharedState.DeepEnhancer();
}

if (string.IsNullOrEmpty(name))
{
name = $"{nameof(ObservableSet<T>)}@{sharedState.GetUniqueId()}";
}

return new ObservableSet<T>(sharedState, enhancer, initialValues, name);
}

/// <summary>
/// Creates an observable Dictionary from an initial dictionary.
/// </summary>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="sharedState">The shared state to operate on.</param>
/// <param name="initialValues">The initial values to use.</param>
/// <param name="name">The name of the observable collection.</param>
/// <param name="enhancer">The optional enhancer to use. default enhancer is the deep enhancer.</param>
/// <returns>The observable.</returns>
public static IDictionary<TKey, TValue> Dictionary<TKey, TValue>(this ISharedState sharedState, IDictionary<TKey, TValue> initialValues = null, string name = null, IEnhancer enhancer = null)
{
if (sharedState is null)
{
throw new ArgumentNullException(nameof(sharedState));
}

if (enhancer is null)
{
enhancer = sharedState.DeepEnhancer();
}

if (string.IsNullOrEmpty(name))
{
name = $"{nameof(ObservableDictionary<TKey, TValue>)}@{sharedState.GetUniqueId()}";
}

return new ObservableDictionary<TKey, TValue>(sharedState, enhancer, initialValues, name);
}
}
}
72 changes: 72 additions & 0 deletions src/Cortex.Net/Cortex.Net.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion src/Cortex.Net/Types/ObservableCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ public class ObservableCollection<T> : ICollection<T>, IEnumerable<T>, IEnumerab
/// <param name="enhancer">The <see cref="IEnhancer"/> implementation to use.</param>
/// <param name="name">The name of the ObservableCollection.</param>
public ObservableCollection(ISharedState sharedState, IEnhancer enhancer, string name = null)
: this(sharedState, enhancer, null, name)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="ObservableCollection{T}"/> class.
/// </summary>
/// <param name="sharedState">The <see cref="ISharedState"/> instance this observableCollection belongs to.</param>
/// <param name="enhancer">The <see cref="IEnhancer"/> implementation to use.</param>
/// <param name="name">The name of the ObservableCollection.</param>
/// <param name="initialValues">The initial values to use.</param>
public ObservableCollection(ISharedState sharedState, IEnhancer enhancer, IEnumerable<T> initialValues, string name = null)
{
this.SharedState = sharedState ?? throw new ArgumentNullException(nameof(sharedState));
this.enhancer = enhancer ?? throw new ArgumentNullException(nameof(enhancer));
Expand All @@ -62,7 +74,7 @@ public ObservableCollection(ISharedState sharedState, IEnhancer enhancer, string
}

this.Name = name;
this.innerList = new List<T>();
this.innerList = initialValues != null ? new List<T>(initialValues) : new List<T>();
this.atom = new Atom(sharedState, name);
}

Expand Down
14 changes: 13 additions & 1 deletion src/Cortex.Net/Types/ObservableDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ public class ObservableDictionary<TKey, TValue> :
/// <param name="enhancer">The <see cref="IEnhancer"/> implementation to use.</param>
/// <param name="name">The name of the ObservableDictionary.</param>
public ObservableDictionary(ISharedState sharedState, IEnhancer enhancer, string name = null)
: this(sharedState, enhancer, null, name)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="ObservableDictionary{TKey, TValue}"/> class.
/// </summary>
/// <param name="sharedState">The <see cref="ISharedState"/> instance this observableDictionary belongs to.</param>
/// <param name="enhancer">The <see cref="IEnhancer"/> implementation to use.</param>
/// <param name="initialValues">The initial values.</param>
/// <param name="name">The name of the ObservableDictionary.</param>
public ObservableDictionary(ISharedState sharedState, IEnhancer enhancer, IDictionary<TKey, TValue> initialValues, string name = null)
{
this.SharedState = sharedState ?? throw new ArgumentNullException(nameof(sharedState));
this.enhancer = enhancer ?? throw new ArgumentNullException(nameof(enhancer));
Expand All @@ -89,7 +101,7 @@ public ObservableDictionary(ISharedState sharedState, IEnhancer enhancer, string
}

this.Name = name;
this.innerDictionary = new Dictionary<TKey, TValue>();
this.innerDictionary = initialValues != null ? new Dictionary<TKey, TValue>(initialValues) : new Dictionary<TKey, TValue>();
this.hasDictionary = new Dictionary<TKey, ObservableValue<bool>>();

this.atom = new Atom(sharedState, name);
Expand Down
14 changes: 13 additions & 1 deletion src/Cortex.Net/Types/ObservableSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@ public class ObservableSet<T> : ICollection<T>, IEnumerable<T>, IEnumerable, IRe
/// <param name="enhancer">The <see cref="IEnhancer"/> implementation to use.</param>
/// <param name="name">The name of the ObservableSet.</param>
public ObservableSet(ISharedState sharedState, IEnhancer enhancer, string name = null)
: this(sharedState, enhancer, null, name)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="ObservableSet{T}"/> class.
/// </summary>
/// <param name="sharedState">The <see cref="ISharedState"/> instance this ObservableSet belongs to.</param>
/// <param name="enhancer">The <see cref="IEnhancer"/> implementation to use.</param>
/// <param name="name">The name of the ObservableSet.</param>
/// <param name="initialItems">The initialItems to use.</param>
public ObservableSet(ISharedState sharedState, IEnhancer enhancer, IEnumerable<T> initialItems, string name = null)
{
this.SharedState = sharedState ?? throw new ArgumentNullException(nameof(sharedState));
this.enhancer = enhancer ?? throw new ArgumentNullException(nameof(enhancer));
Expand All @@ -65,7 +77,7 @@ public ObservableSet(ISharedState sharedState, IEnhancer enhancer, string name =
}

this.Name = name;
this.innerSet = new HashSet<T>();
this.innerSet = initialItems != null ? new HashSet<T>(initialItems) : new HashSet<T>();
this.atom = new Atom(sharedState, name);
}

Expand Down

0 comments on commit 30ff35e

Please sign in to comment.