| File: AppContextSwitchScope.cs | Web Access |
| Project: src\winforms\src\Common\tests\TestUtilities\System.Private.Windows.Core.TestUtilities.csproj (System.Private.Windows.Core.TestUtilities) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. namespace System; /// <summary> /// Scope for temporarily setting an <see cref="AppContext"/> switch. Use in a <see langword="using"/> statement. /// </summary> /// <remarks> /// <para> /// It is recommended to create wrappers for this struct for both simplicity and to allow adding synchronization. /// See <see cref="BinaryFormatterScope"/> for an example of doing this. /// </para> /// </remarks> public readonly ref struct AppContextSwitchScope { private readonly string _switchName; private readonly bool _originalState; public AppContextSwitchScope(string switchName, bool enable) : this(switchName, getDefaultValue: null, enable) { } public AppContextSwitchScope(string switchName, Func<bool>? getDefaultValue, bool enable) { if (!AppContext.TryGetSwitch(AppContextSwitchNames.LocalAppContext_DisableCaching, out bool isEnabled) || !isEnabled) { // It doesn't make sense to try messing with AppContext switches if they are going to be cached. throw new InvalidOperationException("LocalAppContext switch caching is not disabled."); } // AppContext won't have any switch value until it is explicitly set. if (!AppContext.TryGetSwitch(switchName, out _originalState)) { _originalState = getDefaultValue is not null && getDefaultValue(); } AppContext.SetSwitch(switchName, enable); if (!AppContext.TryGetSwitch(switchName, out isEnabled) || isEnabled != enable) { throw new InvalidOperationException($"Could not set {switchName} to {enable}."); } _switchName = switchName; } public void Dispose() { AppContext.SetSwitch(_switchName, _originalState); if (!AppContext.TryGetSwitch(_switchName, out bool isEnabled) || isEnabled != _originalState) { throw new InvalidOperationException($"Could not reset {_switchName} to {_originalState}."); } } /// <summary> /// Gets the default value for a switch via reflection. /// </summary> public static bool GetDefaultValueForSwitchInAssembly(string switchName, string assemblyName, string typeName) { Type type = Type.GetType($"{typeName}, {assemblyName}") ?? throw new InvalidOperationException($"Could not find {typeName} type in {assemblyName} assembly."); return type.TestAccessor.Dynamic.GetSwitchDefaultValue(switchName); } }