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+ }
0 commit comments