Skip to content

Commit bdf5b0e

Browse files
committed
migrate to extension blocks
1 parent 38bb670 commit bdf5b0e

7 files changed

Lines changed: 328 additions & 285 deletions

File tree

src/SMAPI.Internal/ExceptionHelper.cs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,39 @@ internal static class ExceptionHelper
1010
/*********
1111
** Public methods
1212
*********/
13-
/// <summary>Get a string representation of an exception suitable for writing to the error log.</summary>
1413
/// <param name="exception">The error to summarize.</param>
15-
public static string GetLogSummary(this Exception? exception)
14+
extension(Exception? exception)
1615
{
17-
try
16+
/// <summary>Get a string representation of an exception suitable for writing to the error log.</summary>
17+
public string GetLogSummary()
1818
{
19-
string message;
20-
switch (exception)
19+
try
2120
{
22-
case TypeLoadException ex:
23-
message = $"Failed loading type '{ex.TypeName}': {exception}";
24-
break;
21+
string message;
22+
switch (exception)
23+
{
24+
case TypeLoadException ex:
25+
message = $"Failed loading type '{ex.TypeName}': {exception}";
26+
break;
2527

26-
case ReflectionTypeLoadException ex:
27-
string summary = ex.ToString();
28-
foreach (Exception? childEx in ex.LoaderExceptions)
29-
summary += $"\n\n{childEx?.GetLogSummary()}";
30-
message = summary;
31-
break;
28+
case ReflectionTypeLoadException ex:
29+
string summary = ex.ToString();
30+
foreach (Exception? childEx in ex.LoaderExceptions)
31+
summary += $"\n\n{childEx?.GetLogSummary()}";
32+
message = summary;
33+
break;
3234

33-
default:
34-
message = exception?.ToString() ?? $"<null exception>\n{Environment.StackTrace}";
35-
break;
36-
}
35+
default:
36+
message = exception?.ToString() ?? $"<null exception>\n{Environment.StackTrace}";
37+
break;
38+
}
3739

38-
return ExceptionHelper.SimplifyExtensionMessage(message);
39-
}
40-
catch (Exception ex)
41-
{
42-
throw new InvalidOperationException($"Failed handling {exception?.GetType().FullName} (original message: {exception?.Message})", ex);
40+
return ExceptionHelper.SimplifyExtensionMessage(message);
41+
}
42+
catch (Exception ex)
43+
{
44+
throw new InvalidOperationException($"Failed handling {exception?.GetType().FullName} (original message: {exception?.Message})", ex);
45+
}
4346
}
4447
}
4548

src/SMAPI.Toolkit/Serialization/InternalExtensions.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@ namespace StardewModdingAPI.Toolkit.Serialization;
66
/// <summary>Provides extension methods for parsing JSON.</summary>
77
public static class JsonExtensions
88
{
9-
/// <summary>Get a JSON field value from a case-insensitive field name. This will check for an exact match first, then search without case sensitivity.</summary>
10-
/// <typeparam name="T">The value type.</typeparam>
119
/// <param name="obj">The JSON object to search.</param>
12-
/// <param name="fieldName">The field name.</param>
13-
public static T? ValueIgnoreCase<T>(this JObject obj, string fieldName)
10+
extension(JObject obj)
1411
{
15-
JToken? token = obj.GetValue(fieldName, StringComparison.OrdinalIgnoreCase);
16-
return token != null
17-
? token.Value<T>()
18-
: default;
12+
/// <summary>Get a JSON field value from a case-insensitive field name. This will check for an exact match first, then search without case sensitivity.</summary>
13+
/// <typeparam name="T">The value type.</typeparam>
14+
/// <param name="fieldName">The field name.</param>
15+
public T? ValueIgnoreCase<T>(string fieldName)
16+
{
17+
JToken? token = obj.GetValue(fieldName, StringComparison.OrdinalIgnoreCase);
18+
return token != null
19+
? token.Value<T>()
20+
: default;
21+
}
1922
}
2023
}

src/SMAPI.Web/Framework/Extensions.cs

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,54 +19,59 @@ public static class Extensions
1919
/****
2020
** View helpers
2121
****/
22-
/// <summary>Get a URL for an action method. Unlike <see cref="IUrlHelper.Action"/>, only the specified <paramref name="values"/> are added to the URL without merging values from the current HTTP request.</summary>
2322
/// <param name="helper">The URL helper to extend.</param>
24-
/// <param name="action">The name of the action method.</param>
25-
/// <param name="controller">The name of the controller.</param>
26-
/// <param name="values">An object that contains route values.</param>
27-
/// <param name="absoluteUrl">Get an absolute URL instead of a server-relative path/</param>
28-
/// <returns>The generated URL.</returns>
29-
public static string? PlainAction(this IUrlHelper helper, [AspMvcAction] string action, [AspMvcController] string controller, object? values = null, bool absoluteUrl = false)
23+
extension(IUrlHelper helper)
3024
{
31-
// get route values
32-
RouteValueDictionary valuesDict = new(values);
33-
foreach (var value in helper.ActionContext.RouteData.Values)
34-
valuesDict.TryAdd(value.Key, null); // explicitly remove it from the URL
25+
/// <summary>Get a URL for an action method. Unlike <see cref="IUrlHelper.Action"/>, only the specified <paramref name="values"/> are added to the URL without merging values from the current HTTP request.</summary>
26+
/// <param name="action">The name of the action method.</param>
27+
/// <param name="controller">The name of the controller.</param>
28+
/// <param name="values">An object that contains route values.</param>
29+
/// <param name="absoluteUrl">Get an absolute URL instead of a server-relative path/</param>
30+
/// <returns>The generated URL.</returns>
31+
public string? PlainAction([AspMvcAction] string action, [AspMvcController] string controller, object? values = null, bool absoluteUrl = false)
32+
{
33+
// get route values
34+
RouteValueDictionary valuesDict = new(values);
35+
foreach (var value in helper.ActionContext.RouteData.Values)
36+
valuesDict.TryAdd(value.Key, null); // explicitly remove it from the URL
3537

36-
// get relative URL
37-
string? url = helper.Action(action, controller, valuesDict);
38-
if (url == null && action.EndsWith("Async"))
39-
url = helper.Action(action[..^"Async".Length], controller, valuesDict);
38+
// get relative URL
39+
string? url = helper.Action(action, controller, valuesDict);
40+
if (url == null && action.EndsWith("Async"))
41+
url = helper.Action(action[..^"Async".Length], controller, valuesDict);
4042

41-
// get absolute URL
42-
if (absoluteUrl)
43-
{
44-
HttpRequest request = helper.ActionContext.HttpContext.Request;
45-
Uri baseUri = new($"{request.Scheme}://{request.Host}");
46-
url = new Uri(baseUri, url).ToString();
47-
}
43+
// get absolute URL
44+
if (absoluteUrl)
45+
{
46+
HttpRequest request = helper.ActionContext.HttpContext.Request;
47+
Uri baseUri = new($"{request.Scheme}://{request.Host}");
48+
url = new Uri(baseUri, url).ToString();
49+
}
4850

49-
return url;
50-
}
51+
return url;
52+
}
5153

52-
/// <summary>Convert a virtual (relative, starting with ~/) path to an application absolute path, and append a query argument to force browsers to re-download the asset if needed.</summary>
53-
/// <param name="helper">The URL helper to extend.</param>
54-
/// <param name="url">The virtual path of the content.</param>
55-
public static string ContentWithCacheBust(this IUrlHelper helper, string url)
56-
{
57-
char delimiter = url.Contains('?') ? '&' : '?';
54+
/// <summary>Convert a virtual (relative, starting with ~/) path to an application absolute path, and append a query argument to force browsers to re-download the asset if needed.</summary>
55+
/// <param name="url">The virtual path of the content.</param>
56+
public string ContentWithCacheBust(string url)
57+
{
58+
char delimiter = url.Contains('?') ? '&' : '?';
5859

59-
return helper.Content($"{url}{delimiter}v={Program.CacheBustValue}");
60+
return helper.Content($"{url}{delimiter}v={Program.CacheBustValue}");
61+
}
6062
}
6163

62-
/// <summary>Get a serialized JSON representation of the value.</summary>
6364
/// <param name="page">The page to extend.</param>
64-
/// <param name="value">The value to serialize.</param>
65-
/// <returns>The serialized JSON.</returns>
66-
/// <remarks>This bypasses unnecessary validation (e.g. not allowing null values) in <see cref="IJsonHelper.Serialize"/>.</remarks>
67-
public static IHtmlContent ForJson(this RazorPageBase page, object? value)
65+
extension(RazorPageBase page)
6866
{
69-
string json = JsonConvert.SerializeObject(value);
70-
return new HtmlString(json);
67+
/// <summary>Get a serialized JSON representation of the value.</summary>
68+
/// <param name="value">The value to serialize.</param>
69+
/// <returns>The serialized JSON.</returns>
70+
/// <remarks>This bypasses unnecessary validation (e.g. not allowing null values) in <see cref="IJsonHelper.Serialize"/>.</remarks>
71+
public IHtmlContent ForJson(object? value)
72+
{
73+
string json = JsonConvert.SerializeObject(value);
74+
return new HtmlString(json);
75+
}
7176
}
7277
}

0 commit comments

Comments
 (0)