Tools

Add Ansight tool suites to a .NET app, gate them with MSBuild and ToolGuard, and keep them limited to local development workflows, including live reflection.

The base Ansight package defines the tool abstraction layer, but the concrete tool suites ship in separate packages.

Important Security Rule

Treat all remote tools as development-only capabilities.

Do this:

  • install tool packages only in local Debug builds
  • set AnsightAllowRemoteTools=true only for those Debug builds
  • use the narrowest runtime guard that works for the workflow

Do not do this:

  • ship tool packages in Release or distribution builds
  • enable AnsightAllowRemoteTools broadly
  • expose write or delete tools when read-only inspection is enough

Build-Time Opt-In

The base package scans the build output for concrete ITool implementations.

If it finds them and AnsightAllowRemoteTools is not enabled, the build fails on purpose.

Recommended pattern:

<ItemGroup Condition="'$(Configuration)' == 'Debug'">
  <PackageReference Include="Ansight.Tools.VisualTree" Version="*" />
  <PackageReference Include="Ansight.Tools.Reflection" Version="*" />
  <PackageReference Include="Ansight.Tools.Database" Version="*" />
</ItemGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
  <AnsightAllowRemoteTools>true</AnsightAllowRemoteTools>
</PropertyGroup>

Notes:

  • AnsightAllowRemoteTools=true on non-Debug configurations triggers a warning.

Runtime Registration

Register each suite explicitly:

using Ansight;
using Ansight.Tools.Reflection;
using Ansight.Tools.Database;
using Ansight.Tools.VisualTree;

var options = Options.CreateBuilder()
    .WithVisualTreeTools()
    .WithReflectionTools(reflection =>
    {
        reflection.WithAssemblyTraversalMode(ReflectionAssemblyTraversalMode.AllowAll);
        reflection.WithNamespaceTraversalMode(ReflectionNamespaceTraversalMode.AllowAll);
        reflection.AddRoot(
            "session",
            new DebugSessionViewModel(),
            new ReflectionRootMetadata("Current Session"));
    })
    .WithDatabaseTools()
    .WithReadOnlyToolAccess()
    .Build();

Registered tools stay unusable until the guard allows them.

Suite Registration API

The package-specific entry points are:

SuiteCommon registration API
VisualTreeWithVisualTreeTools()
ReflectionWithReflectionTools(...), AddRoot(...), AddStrongRoot(...), WithAssemblyTraversalMode(...), WithNamespaceTraversalMode(...), AllowAssembly(...), AllowNamespacePrefix(...), AllowWritableMembers(...), AllowAllWritableMembersOn<T>(...), AllowAllWritableMembers(), AllowInvokableMethods(...), AllowAllInvokableMethodsOn<T>(...), AllowAllInvokableMethods()
DatabaseWithDatabaseTools()
FileSystemWithFileSystemTools(...), AddRoot(tag, path)
PreferencesWithPreferencesTools(...), WithDefaultStore(...), AllowStore(...), AllowKey(...), AllowKeyPrefix(...)
SecureStorageWithSecureStorageTools(...), WithStorageIdentifier(...), WithAndroidStore(...), WithAppleService(...), AllowKey(...), AllowKeyPrefix(...)

Guard Levels

GuardWhat it allows
WithToolsDisabled()No discovery, no execution.
WithReadOnlyToolAccess()Read-scoped tools only.
WithReadWriteToolAccess()Read and write tools. Delete tools remain blocked.
WithAllToolAccess()Read, write, and delete tools.

Storage-package remove operations are Delete. Reflection writes and method invocations are Write.

Tool Suites

SuitePackageTypical use
VisualTreeAnsight.Tools.VisualTreeInspect the live UI hierarchy and capture screenshots.
ReflectionAnsight.Tools.ReflectionInspect registered live objects, describe runtime types, and optionally allow scoped writes or method invocation.
DatabaseAnsight.Tools.DatabaseDiscover SQLite databases, inspect schema, and run read-only queries.
FileSystemAnsight.Tools.FileSystemList directories, read files, and download sandboxed files.
PreferencesAnsight.Tools.PreferencesRead and mutate shared preferences or user defaults under allow-lists.
SecureStorageAnsight.Tools.SecureStorageRead and mutate secure storage values under explicit key allow-lists.

For most teams:

  1. Start with VisualTree and Database.
  2. Add Reflection when you need live in-memory state instead of persisted data.
  3. Use WithReadOnlyToolAccess().
  4. Add FileSystem, Preferences, or SecureStorage only when there is a specific debugging workflow that needs them.
  5. Keep write and delete operations off unless the workflow genuinely depends on them.