Skip to content

Commit 93ee7fb

Browse files
authored
Optimize retrieval of simple name from Assembly.FullName, fix up faulty methods (#9739)
* Move reflection helpers to ReflectionUtils file * Use GetAssemblyPartialName in more places * Few more places to use ReflectionUtils in * Add some more comments * Introduce fast simple assembly name parsing (300ns -> 10ns) * Remove faulty implementations that cannot parse assemblyName with escaped commas * ReadOnlySpan<char> adjustments, enable nullable context, unescape properly * Let's not forget this shall be Ordinal search * Fix missing using after merge conflict * Address post-merge using issues * Fix fallback mechanism for escapes
1 parent 17f6fad commit 93ee7fb

File tree

19 files changed

+125
-78
lines changed

19 files changed

+125
-78
lines changed

src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/PresentationBuildTasks.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@
8585
<Compile Include="$(WpfSharedDir)\MS\Internal\ResourceIDHelper.cs">
8686
<Link>Shared\MS\Internal\ResourceIDHelper.cs</Link>
8787
</Compile>
88+
<Compile Include="$(WpfSharedDir)\MS\Internal\ReflectionUtils.cs">
89+
<Link>Shared\MS\Internal\ReflectionUtils.cs</Link>
90+
</Compile>
8891
<Compile Include="$(WpfSharedDir)\MS\Internal\SecurityHelper.cs">
8992
<Link>Shared\MS\Internal\SecurityHelper.cs</Link>
9093
</Compile>

src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/FontCache/FontSource.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,8 @@ private Stream GetCompositeFontResourceStream()
355355
{
356356
string fontFilename = _fontUri.OriginalString.Substring(_fontUri.OriginalString.LastIndexOf('/') + 1).ToLowerInvariant();
357357

358-
var fontResourceAssembly = Assembly.GetExecutingAssembly();
359-
ResourceManager rm = new ResourceManager($"{fontResourceAssembly.GetName().Name}.g", fontResourceAssembly);
358+
Assembly fontResourceAssembly = Assembly.GetExecutingAssembly();
359+
ResourceManager rm = new($"{ReflectionUtils.GetAssemblyPartialName(fontResourceAssembly)}.g", fontResourceAssembly);
360360

361361
return rm?.GetStream($"fonts/{fontFilename}");
362362
}

src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Resources/ResourceManagerWrapper.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,10 @@ private ResourceSet ResourceSet
232232
{
233233
if (_resourceSet == null)
234234
{
235-
string manifestResourceName;
235+
//"$(AssemblyShortname).unlocalizable.g"
236+
string manifestResourceName = $"{ReflectionUtils.GetAssemblyPartialName(_assembly)}{UnLocalizableResourceNameSuffix}";
237+
ResourceManager manager = new(manifestResourceName, _assembly);
236238

237-
manifestResourceName = SafeSecurityHelper.GetAssemblyPartialName(_assembly) + UnLocalizableResourceNameSuffix;
238-
239-
ResourceManager manager = new ResourceManager(manifestResourceName, this._assembly);
240239
_resourceSet = manager.GetResourceSet(CultureInfo.InvariantCulture, true, false);
241240
}
242241

@@ -254,11 +253,9 @@ private ResourceManager ResourceManager
254253
{
255254
if (_resourceManager == null)
256255
{
257-
string baseResourceName; // Our build system always generate a resource base name "$(AssemblyShortname).g"
258-
259-
baseResourceName = SafeSecurityHelper.GetAssemblyPartialName(_assembly) + LocalizableResourceNameSuffix;
260-
261-
_resourceManager = new ResourceManager(baseResourceName, this._assembly);
256+
// Our build system always generate a resource base name "$(AssemblyShortname).g"
257+
string baseResourceName = $"{ReflectionUtils.GetAssemblyPartialName(_assembly)}{LocalizableResourceNameSuffix}";
258+
_resourceManager = new ResourceManager(baseResourceName, _assembly);
262259
}
263260

264261
return _resourceManager;

src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/InterOp/HwndSourceParameters.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
3-
// See the LICENSE file in the project root for more information.
43

5-
using MS.Win32;
64
using System.Windows.Input;
5+
using System.Reflection;
6+
using MS.Internal;
7+
using MS.Win32;
78

89
namespace System.Windows.Interop
910
{
@@ -418,7 +419,7 @@ internal static bool PlatformSupportsTransparentChildWindows
418419
/// <remarks>Not intended to be tested outside test code</remarks>
419420
internal static void SetPlatformSupportsTransparentChildWindowsForTestingOnly(bool value)
420421
{
421-
if (string.Equals(System.Reflection.Assembly.GetEntryAssembly().GetName().Name, "drthwndsource", StringComparison.CurrentCultureIgnoreCase))
422+
if (ReflectionUtils.GetAssemblyPartialName(Assembly.GetEntryAssembly()).Equals("drthwndsource", StringComparison.CurrentCultureIgnoreCase))
422423
{
423424
_platformSupportsTransparentChildWindows = value;
424425
}

src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Navigation/BaseUriHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ static internal bool IsComponentEntryAssembly(string component)
327327

328328
if (assembly != null)
329329
{
330-
return (string.Equals(SafeSecurityHelper.GetAssemblyPartialName(assembly), assemblyName, StringComparison.OrdinalIgnoreCase));
330+
return ReflectionUtils.GetAssemblyPartialName(assembly).Equals(assemblyName, StringComparison.OrdinalIgnoreCase);
331331
}
332332
else
333333
{

src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/documents/DocumentsTrace.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ static DocumentsTrace()
117117
public DocumentsTrace(string switchName)
118118
{
119119
#if DEBUG
120-
string name = SafeSecurityHelper.GetAssemblyPartialName( Assembly.GetCallingAssembly() );
121-
_switch = new BooleanSwitch(switchName, $"[{name}]");
120+
ReadOnlySpan<char> shortAssemblyName = ReflectionUtils.GetAssemblyPartialName(Assembly.GetCallingAssembly());
121+
_switch = new BooleanSwitch(switchName, $"[{shortAssemblyName}]");
122122
#endif
123123
}
124124

src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/Baml2006Reader.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using System.Globalization;
1313
using XamlReaderHelper = System.Windows.Markup.XamlReaderHelper;
1414
using System.Runtime.CompilerServices;
15+
using MS.Internal;
1516

1617
namespace System.Windows.Baml2006
1718
{
@@ -2105,11 +2106,9 @@ private string Logic_GetFullXmlns(string uriInput)
21052106

21062107
// Providing the assembly short name may lead to ambiguity between two versions of the same assembly, but we need to
21072108
// keep it this way since it is exposed publicly via the Namespace property, Baml2006ReaderInternal provides the full Assembly name.
2108-
// We need to avoid Assembly.GetName() so we run in PartialTrust without asserting.
21092109
internal virtual ReadOnlySpan<char> GetAssemblyNameForNamespace(Assembly assembly)
21102110
{
2111-
string assemblyLongName = assembly.FullName;
2112-
return assemblyLongName.AsSpan(0, assemblyLongName.IndexOf(','));
2111+
return ReflectionUtils.GetAssemblyPartialName(assembly);
21132112
}
21142113

21152114
// (prefix, namespaceUri)

src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/Baml2006ReaderInternal.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ internal Baml2006ReaderInternal(
3434
#endregion
3535

3636
// Return the full assembly name, this includes the assembly version
37-
internal override ReadOnlySpan<char> GetAssemblyNameForNamespace(Assembly asm)
37+
internal override ReadOnlySpan<char> GetAssemblyNameForNamespace(Assembly assembly)
3838
{
39-
return asm.FullName;
39+
return assembly.FullName;
4040
}
4141

4242
// When processing ResourceDictionary.Source we may find a Uri that references the

src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Primitives/MarkupWriter.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
3-
// See the LICENSE file in the project root for more information.
43

54
//
65
// Contents: XAML writer
76
//
87

8+
using System.Xml.Serialization;
99
using System.ComponentModel;
10-
using System.Reflection;
1110
using System.Collections;
11+
using System.Reflection;
12+
using MS.Internal;
1213
using System.Text;
1314
using System.Xml;
14-
using System.Xml.Serialization;
1515

1616
namespace System.Windows.Markup.Primitives
1717
{
@@ -1610,14 +1610,14 @@ public static string GetNamespaceUriFor(Type type)
16101610
{
16111611
if (type.Namespace == null)
16121612
{
1613-
result = $"{clrUriPrefix};assembly={type.Assembly.GetName().Name}";
1613+
result = $"{clrUriPrefix};assembly={ReflectionUtils.GetAssemblyPartialName(type.Assembly)}";
16141614
}
16151615
else
16161616
{
16171617
Dictionary<string, string> namespaceToUri = GetMappingsFor(type.Assembly);
16181618
if (!namespaceToUri.TryGetValue(type.Namespace, out result))
16191619
{
1620-
result = $"{clrUriPrefix}{type.Namespace};assembly={type.Assembly.GetName().Name}";
1620+
result = $"{clrUriPrefix}{type.Namespace};assembly={ReflectionUtils.GetAssemblyPartialName(type.Assembly)}";
16211621
}
16221622
}
16231623
}

src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlTypeMapper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2481,7 +2481,7 @@ private static bool IsFriendAssembly(Assembly assembly)
24812481

24822482
private static bool IsInternalAllowedOnType(Type type)
24832483
{
2484-
bool isInternalAllowed = ReflectionHelper.LocalAssemblyName == type.Assembly.GetName().Name ||
2484+
bool isInternalAllowed = ReflectionHelper.LocalAssemblyName == ReflectionUtils.GetAssemblyPartialName(type.Assembly) ||
24852485
IsFriendAssembly(type.Assembly);
24862486
_hasInternals = _hasInternals || isInternalAllowed;
24872487
return isInternalAllowed;

0 commit comments

Comments
 (0)