forked from modelcontextprotocol/csharp-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMcpServerPrimitiveCollection.cs
More file actions
162 lines (136 loc) · 6.77 KB
/
McpServerPrimitiveCollection.cs
File metadata and controls
162 lines (136 loc) · 6.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
using System.Collections;
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
namespace ModelContextProtocol.Server;
/// <summary>Provides a thread-safe collection of <typeparamref name="T"/> instances, indexed by their names.</summary>
/// <typeparam name="T">Specifies the type of primitive stored in the collection.</typeparam>
public class McpServerPrimitiveCollection<T> : ICollection<T>, IReadOnlyCollection<T>
where T : IMcpServerPrimitive
{
/// <summary>Concurrent dictionary of primitives, indexed by their names.</summary>
private readonly ConcurrentDictionary<string, T> _primitives = [];
/// <summary>
/// Initializes a new instance of the <see cref="McpServerPrimitiveCollection{T}"/> class.
/// </summary>
public McpServerPrimitiveCollection()
{
}
/// <summary>Occurs when the collection is changed.</summary>
/// <remarks>
/// By default, this is raised when a primitive is added or removed. However, a derived implementation
/// may raise this event for other reasons, such as when a primitive is modified.
/// </remarks>
public event EventHandler? Changed;
/// <summary>Gets the number of primitives in the collection.</summary>
public int Count => _primitives.Count;
/// <summary>Gets whether there are any primitives in the collection.</summary>
public bool IsEmpty => _primitives.IsEmpty;
/// <summary>Raises <see cref="Changed"/> if there are registered handlers.</summary>
protected void RaiseChanged() => Changed?.Invoke(this, EventArgs.Empty);
/// <summary>Gets the <typeparamref name="T"/> with the specified <paramref name="name"/> from the collection.</summary>
/// <param name="name">The name of the primitive to retrieve.</param>
/// <returns>The <typeparamref name="T"/> with the specified name.</returns>
/// <exception cref="ArgumentNullException"><paramref name="name"/> is <see langword="null"/>.</exception>
/// <exception cref="KeyNotFoundException">An primitive with the specified name does not exist in the collection.</exception>
public T this[string name]
{
get
{
Throw.IfNull(name);
return _primitives[name];
}
}
/// <summary>Clears all primitives from the collection.</summary>
public virtual void Clear()
{
_primitives.Clear();
RaiseChanged();
}
/// <summary>Adds the specified <typeparamref name="T"/> to the collection.</summary>
/// <param name="primitive">The primitive to be added.</param>
/// <exception cref="ArgumentNullException"><paramref name="primitive"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentException">A primitive with the same name as <paramref name="primitive"/> already exists in the collection.</exception>
public void Add(T primitive)
{
if (!TryAdd(primitive))
{
throw new ArgumentException($"A primitive with the same name '{primitive.Id}' already exists in the collection.", nameof(primitive));
}
}
/// <summary>Adds the specified <typeparamref name="T"/> to the collection.</summary>
/// <param name="primitive">The primitive to be added.</param>
/// <returns><see langword="true"/> if the primitive was added; otherwise, <see langword="false"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="primitive"/> is <see langword="null"/>.</exception>
public virtual bool TryAdd(T primitive)
{
Throw.IfNull(primitive);
bool added = _primitives.TryAdd(primitive.Id, primitive);
if (added)
{
RaiseChanged();
}
return added;
}
/// <summary>Removes the specified primitivefrom the collection.</summary>
/// <param name="primitive">The primitive to be removed from the collection.</param>
/// <returns>
/// <see langword="true"/> if the primitive was found in the collection and removed; otherwise, <see langword="false"/> if it couldn't be found.
/// </returns>
/// <exception cref="ArgumentNullException"><paramref name="primitive"/> is <see langword="null"/>.</exception>
public virtual bool Remove(T primitive)
{
Throw.IfNull(primitive);
bool removed = ((ICollection<KeyValuePair<string, T>>)_primitives).Remove(new(primitive.Id, primitive));
if (removed)
{
RaiseChanged();
}
return removed;
}
/// <summary>Attempts to get the primitive with the specified name from the collection.</summary>
/// <param name="name">The name of the primitive to retrieve.</param>
/// <param name="primitive">The primitive, if found; otherwise, <see langword="null"/>.</param>
/// <returns>
/// <see langword="true"/> if the primitive was found in the collection and return; otherwise, <see langword="false"/> if it couldn't be found.
/// </returns>
/// <exception cref="ArgumentNullException"><paramref name="name"/> is <see langword="null"/>.</exception>
public virtual bool TryGetPrimitive(string name, [NotNullWhen(true)] out T? primitive)
{
Throw.IfNull(name);
return _primitives.TryGetValue(name, out primitive);
}
/// <summary>Checks if a specific primitive is present in the collection of primitives.</summary>
/// <param name="primitive">The primitive to search for in the collection.</param>
/// <see langword="true"/> if the primitive was found in the collection and return; otherwise, <see langword="false"/> if it couldn't be found.
/// <exception cref="ArgumentNullException"><paramref name="primitive"/> is <see langword="null"/>.</exception>
public virtual bool Contains(T primitive)
{
Throw.IfNull(primitive);
return ((ICollection<KeyValuePair<string, T>>)_primitives).Contains(new(primitive.Id, primitive));
}
/// <summary>Gets the names of all of the primitives in the collection.</summary>
public virtual ICollection<string> PrimitiveNames => _primitives.Keys;
/// <summary>Creates an array containing all of the primitives in the collection.</summary>
/// <returns>An array containing all of the primitives in the collection.</returns>
public virtual T[] ToArray() => _primitives.Values.ToArray();
/// <inheritdoc/>
public virtual void CopyTo(T[] array, int arrayIndex)
{
Throw.IfNull(array);
_primitives.Values.CopyTo(array, arrayIndex);
}
/// <inheritdoc/>
public virtual IEnumerator<T> GetEnumerator()
{
foreach (var entry in _primitives)
{
yield return entry.Value;
}
}
/// <inheritdoc/>
IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
/// <inheritdoc/>
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
/// <inheritdoc/>
bool ICollection<T>.IsReadOnly => false;
}