Skip to content

Commit 9d92a3f

Browse files
committed
Added Chain type for chaining actions over instances of the same type
1 parent a5facb1 commit 9d92a3f

2 files changed

Lines changed: 131 additions & 0 deletions

File tree

src/MADE.Runtime/Actions/Chain.cs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
namespace MADE.Runtime.Actions
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Threading.Tasks;
7+
8+
/// <summary>
9+
/// Defines an implementation for a chain of objects.
10+
/// </summary>
11+
/// <typeparam name="T">The type of object being chained.</typeparam>
12+
public class Chain<T> : IChain<T>
13+
where T : class
14+
{
15+
private readonly List<WeakReference<T>> chain = new List<WeakReference<T>>();
16+
17+
/// <summary>
18+
/// Initializes a new instance of the <see cref="Chain{T}"/> class with an instance.
19+
/// </summary>
20+
/// <param name="instance">The instance to begin the chain.</param>
21+
public Chain(T instance)
22+
{
23+
this.chain.Add(new WeakReference<T>(instance));
24+
}
25+
26+
/// <summary>
27+
/// Initializes a new instance of the <see cref="Chain{T}"/> class with a collection of instances.
28+
/// </summary>
29+
/// <param name="instances">The instances to begin the chain.</param>
30+
public Chain(IEnumerable<T> instances)
31+
{
32+
this.chain.AddRange(instances.Select(i => new WeakReference<T>(i)));
33+
}
34+
35+
/// <summary>
36+
/// Concatenates the current instances in the chain with the specified instance.
37+
/// </summary>
38+
/// <param name="instance">The instance to chain.</param>
39+
/// <returns>The updated <see cref="Chain{T}"/>.</returns>
40+
public Chain<T> With(T instance)
41+
{
42+
this.chain.Add(new WeakReference<T>(instance));
43+
return this;
44+
}
45+
46+
/// <summary>
47+
/// Concatenates the current instances in the chain with the specified instances.
48+
/// </summary>
49+
/// <param name="instances">The instances to chain.</param>
50+
/// <returns>The updated <see cref="Chain{T}"/></returns>
51+
public Chain<T> With(IEnumerable<T> instances)
52+
{
53+
this.chain.AddRange(instances.Select(i => new WeakReference<T>(i)));
54+
return this;
55+
}
56+
57+
/// <summary>
58+
/// Invokes an action with the chain.
59+
/// </summary>
60+
/// <param name="func">The action to invoke.</param>
61+
/// <exception cref="Exception">Potential exceptions thrown if delegate callback throws an exception.</exception>
62+
public void Invoke(Action<T> func)
63+
{
64+
foreach (WeakReference<T> instance in this.chain)
65+
{
66+
if (instance.TryGetTarget(out T i))
67+
{
68+
func(i);
69+
}
70+
}
71+
}
72+
73+
/// <summary>
74+
/// Invokes an asynchronous action with the chain.
75+
/// </summary>
76+
/// <param name="func">The asynchronous action to invoke.</param>
77+
/// <returns>An asynchronous operation.</returns>
78+
/// <exception cref="Exception">Potential exceptions thrown if delegate callback throws an exception.</exception>
79+
public async Task InvokeAsync(Func<T, Task> func)
80+
{
81+
foreach (WeakReference<T> instance in this.chain)
82+
{
83+
if (instance.TryGetTarget(out T i))
84+
{
85+
await func(i);
86+
}
87+
}
88+
}
89+
}
90+
}

src/MADE.Runtime/Actions/IChain.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
namespace MADE.Runtime.Actions
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Threading.Tasks;
6+
7+
/// <summary>
8+
/// Defines an interface for a chain of objects.
9+
/// </summary>
10+
/// <typeparam name="T">The type of object being chained.</typeparam>
11+
public interface IChain<T>
12+
where T : class
13+
{
14+
/// <summary>
15+
/// Concatenates the current instances in the chain with the specified instance.
16+
/// </summary>
17+
/// <param name="instance">The instance to chain.</param>
18+
/// <returns>The updated <see cref="Chain{T}"/>.</returns>
19+
Chain<T> With(T instance);
20+
21+
/// <summary>
22+
/// Concatenates the current instances in the chain with the specified instances.
23+
/// </summary>
24+
/// <param name="instances">The instances to chain.</param>
25+
/// <returns>The updated <see cref="Chain{T}"/></returns>
26+
Chain<T> With(IEnumerable<T> instances);
27+
28+
/// <summary>
29+
/// Invokes an action with the chain.
30+
/// </summary>
31+
/// <param name="func">The action to invoke.</param>
32+
void Invoke(Action<T> func);
33+
34+
/// <summary>
35+
/// Invokes an asynchronous action with the chain.
36+
/// </summary>
37+
/// <param name="func">The asynchronous action to invoke.</param>
38+
/// <returns>An asynchronous operation.</returns>
39+
Task InvokeAsync(Func<T, Task> func);
40+
}
41+
}

0 commit comments

Comments
 (0)