| File: ContractRegistry.cs | Web Access |
| Project: src\runtime\src\native\managed\cdac\Microsoft.Diagnostics.DataContractReader.Abstractions\Microsoft.Diagnostics.DataContractReader.Abstractions.csproj (Microsoft.Diagnostics.DataContractReader.Abstractions) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics.CodeAnalysis; using Microsoft.Diagnostics.DataContractReader.Contracts; namespace Microsoft.Diagnostics.DataContractReader; /// <summary> /// A registry of all the contracts that may be provided by a target. /// </summary> public abstract class ContractRegistry { /// <summary> /// Gets an instance of the Exception contract for the target. /// </summary> public virtual IException Exception => GetContract<IException>(); /// <summary> /// Gets an instance of the Loader contract for the target. /// </summary> public virtual ILoader Loader => GetContract<ILoader>(); /// <summary> /// Gets an instance of the EcmaMetadata contract for the target. /// </summary> public virtual IEcmaMetadata EcmaMetadata => GetContract<IEcmaMetadata>(); /// <summary> /// Gets an instance of the Object contract for the target. /// </summary> public virtual IObject Object => GetContract<IObject>(); /// <summary> /// Gets an instance of the Thread contract for the target. /// </summary> public virtual IThread Thread => GetContract<IThread>(); /// <summary> /// Gets an instance of the WindowsErrorReporting contract for the target. /// </summary> public virtual IWindowsErrorReporting WindowsErrorReporting => GetContract<IWindowsErrorReporting>(); /// <summary> /// Gets an instance of the RuntimeTypeSystem contract for the target. /// </summary> public virtual IRuntimeTypeSystem RuntimeTypeSystem => GetContract<IRuntimeTypeSystem>(); /// <summary> /// Gets an instance of the DacStreams contract for the target. /// </summary> public virtual IDacStreams DacStreams => GetContract<IDacStreams>(); /// <summary> /// Gets an instance of the ExecutionManager contract for the target. /// </summary> public virtual IExecutionManager ExecutionManager => GetContract<IExecutionManager>(); /// <summary> /// Gets an instance of the CodeVersions contract for the target. /// </summary> public virtual ICodeVersions CodeVersions => GetContract<ICodeVersions>(); /// <summary> /// Gets an instance of the PlatformMetadata contract for the target. /// </summary> public virtual IPlatformMetadata PlatformMetadata => GetContract<IPlatformMetadata>(); /// <summary> /// Gets an instance of the FeatureFlags contract for the target. /// </summary> public virtual IFeatureFlags FeatureFlags => GetContract<IFeatureFlags>(); /// <summary> /// Gets an instance of the PrecodeStubs contract for the target. /// </summary> public virtual IPrecodeStubs PrecodeStubs => GetContract<IPrecodeStubs>(); /// <summary> /// Gets an instance of the ReJIT contract for the target. /// </summary> public virtual IReJIT ReJIT => GetContract<IReJIT>(); /// <summary> /// Gets an instance of the StackWalk contract for the target. /// </summary> public virtual IStackWalk StackWalk => GetContract<IStackWalk>(); /// <summary> /// Gets an instance of the RuntimeInfo contract for the target. /// </summary> public virtual IRuntimeInfo RuntimeInfo => GetContract<IRuntimeInfo>(); /// <summary> /// Gets an instance of the ComWrappers contract for the target. /// </summary> public virtual IComWrappers ComWrappers => GetContract<IComWrappers>(); /// Gets an instance of the DebugInfo contract for the target. /// </summary> public virtual IDebugInfo DebugInfo => GetContract<IDebugInfo>(); /// <summary> /// Gets an instance of the SHash contract for the target. /// </summary> public virtual ISHash SHash => GetContract<ISHash>(); /// <summary> /// Gets an instance of the GC contract for the target. /// </summary> public virtual IGC GC => GetContract<IGC>(); /// <summary> /// Gets an instance of the GCInfo contract for the target. /// </summary> public virtual IGCInfo GCInfo => GetContract<IGCInfo>(); /// <summary> /// Gets an instance of the Notifications contract for the target. /// </summary> public virtual INotifications Notifications => GetContract<INotifications>(); /// <summary> /// Gets an instance of the CallingConvention contract for the target. /// </summary> public virtual ICallingConvention CallingConvention => GetContract<ICallingConvention>(); /// <summary> /// Gets an instance of the CodeNotifications contract for the target. /// </summary> public virtual ICodeNotifications CodeNotifications => GetContract<ICodeNotifications>(); /// <summary> /// Gets an instance of the Signature contract for the target. /// </summary> public virtual ISignature Signature => GetContract<ISignature>(); /// <summary> /// Gets an instance of the SyncBlock contract for the target. /// </summary> public virtual ISyncBlock SyncBlock => GetContract<ISyncBlock>(); /// <summary> /// Gets an instance of the BuiltInCOM contract for the target. /// </summary> public virtual IBuiltInCOM BuiltInCOM => GetContract<IBuiltInCOM>(); /// <summary> /// Gets an instance of the ObjectiveCMarshal contract for the target. /// </summary> public virtual IObjectiveCMarshal ObjectiveCMarshal => GetContract<IObjectiveCMarshal>(); /// <summary> /// Gets an instance of the ConditionalWeakTable contract for the target. /// </summary> public virtual IConditionalWeakTable ConditionalWeakTable => GetContract<IConditionalWeakTable>(); /// <summary> /// Gets an instance of the ManagedTypeSource contract for the target. /// </summary> public virtual IManagedTypeSource ManagedTypeSource => GetContract<IManagedTypeSource>(); /// <summary> /// Gets an instance of the AuxiliarySymbols contract for the target. /// </summary> public virtual IAuxiliarySymbols AuxiliarySymbols => GetContract<IAuxiliarySymbols>(); /// <summary> /// Gets an instance of the Debugger contract for the target. /// </summary> public virtual IDebugger Debugger => GetContract<IDebugger>(); /// <summary> /// Gets an instance of the StressLog contract for the target. /// </summary> public virtual IStressLog StressLog => GetContract<IStressLog>(); /// <summary> /// Gets an instance of the RuntimeMutableTypeSystem contract for the target. /// </summary> public virtual IRuntimeMutableTypeSystem RuntimeMutableTypeSystem => GetContract<IRuntimeMutableTypeSystem>(); /// <summary> /// Attempts to get an instance of the requested contract for the target. /// </summary> /// <typeparam name="TContract">The contract type to retrieve.</typeparam> /// <param name="contract"> /// When this method returns <see langword="true"/>, contains the requested contract instance; otherwise, <see langword="null"/>. /// </param> /// <param name="failureException"> /// When this method returns <see langword="false"/>, contains the exception that describes why the contract could not be retrieved; otherwise, <see langword="null"/>. /// </param> /// <returns> /// <see langword="true"/> if the requested contract is present and was retrieved successfully; <see langword="false"/> if the contract is not present or registered"/>. /// </returns> public abstract bool TryGetContract<TContract>([NotNullWhen(true)] out TContract contract, [NotNullWhen(false)] out System.Exception? failureException) where TContract : IContract; public TContract GetContract<TContract>() where TContract : IContract { if (!TryGetContract(out TContract contract, out System.Exception? failureException)) { throw failureException ?? new ContractMissingException(TContract.Name); } return contract; } public bool TryGetContract<TContract>([NotNullWhen(true)] out TContract contract) where TContract : IContract { return TryGetContract(out contract, out _); } /// <summary> /// Determines whether this cDAC can provide the requested contract for the target. Implementations /// should resolve the target-advertised version against the registered implementations only, without /// instantiating the contract, so that validation performs no target memory reads (safe on partial or /// triage dumps) and never triggers contract-to-contract chaining. /// </summary> /// <typeparam name="TContract">The contract type to validate.</typeparam> /// <param name="failureException"> /// When this method returns <see langword="false"/>, contains the exception describing why the /// contract cannot be provided; otherwise, <see langword="null"/>. /// </param> /// <returns> /// <see langword="true"/> if the contract is advertised by the target and a matching implementation /// is registered; otherwise, <see langword="false"/>. /// </returns> /// <remarks> /// The default implementation delegates to <see cref="TryGetContract{TContract}(out TContract, out System.Exception?)"/>, /// which instantiates the contract and therefore does read target memory. Registries that need the /// no-instantiation guarantee above must override this method (<c>CachingContractRegistry</c> does). /// </remarks> public virtual bool TryValidate<TContract>([NotNullWhen(false)] out System.Exception? failureException) where TContract : IContract { return TryGetContract<TContract>(out _, out failureException); } /// <summary> /// Register a contract implementation for a specific version. /// External packages use this to add contract versions or entirely new contract interfaces. /// </summary> public abstract void Register<TContract>(string version, Func<Target, TContract> creator) where TContract : IContract; /// <summary> /// Register a contract version that is recognized but intentionally not implemented. /// </summary> public abstract void RegisterUnsupported<TContract>(string version) where TContract : IContract; /// <summary> /// Flush all cached data held by contracts in this registry for the given /// <paramref name="scope"/>. Called when the target process state may have changed /// (e.g. on resume) or as part of a stress-harness re-read of live target state. /// </summary> public abstract void Flush(FlushScope scope); }