Add OrtEnv.DisableDllImportResolver to prevent fatal error on resolver conflict (#27535)
## Description
`NativeLibrary.SetDllImportResolver()` can only be called once per
assembly. If a host application registers its own `DllImportResolver`
for the ONNX Runtime assembly before any ORT API is used, ORT's internal
call to `SetDllImportResolver` in the `NativeMethods` static constructor
throws an `InvalidOperationException`, which surfaces as a fatal
`TypeInitializationException` — making ONNX Runtime completely unusable.
This PR adds two complementary safeguards:
1. **`try/catch(InvalidOperationException)`** around the
`SetDllImportResolver` call in `NativeMethods..cctor`, so that if a
resolver is already registered, ORT logs a diagnostic trace and
continues normally.
2. **`OrtEnv.DisableDllImportResolver`** — a public static `bool`
property that allows callers to explicitly opt out of ORT's resolver
registration before any ORT type is accessed. This is useful when the
host application needs full control over native library resolution.
### Usage
```csharp
// Option 1: Opt out before any ORT usage
OrtEnv.DisableDllImportResolver = true;
NativeLibrary.SetDllImportResolver(typeof(OrtEnv).Assembly, MyCustomResolver);
var env = OrtEnv.Instance();
// Option 2: Do nothing — if a resolver is already registered,
// ORT catches the conflict and continues using the existing resolver.
```
## Motivation and Context
When a library client has already called `SetDllImportResolver()` for
the ORT assembly (e.g., to handle platform-specific library loading),
ORT's attempt to register its own resolver causes a fatal, unrecoverable
error. This change makes ORT resilient to this scenario and gives
clients explicit control.
## Changes
### `csharp/src/Microsoft.ML.OnnxRuntime/OrtEnv.shared.cs`
- Added `public static bool DisableDllImportResolver` property with XML
documentation and usage example.
### `csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs`
- Wrapped `NativeLibrary.SetDllImportResolver` in `if
(!OrtEnv.DisableDllImportResolver)` guard.
- Added `try/catch(InvalidOperationException)` with a `Trace.WriteLine`
diagnostic message.
### `csharp/test/Microsoft.ML.OnnxRuntime.Tests.Common/OrtEnvTests.cs`
- Added `OrtEnvExternalDllImportResolverTest` test class with two tests
using `AssemblyLoadContext` for process-level isolation of static
constructor behavior:
- **`TestExternalResolverRegisteredFirst`** — Registers an external
resolver FIRST, then initializes ORT. Verifies the `try/catch` prevents
a fatal error and ORT remains fully functional (`GetVersionString()`
succeeds).
- **`TestDisableDllImportResolverWorks`** — Sets
`DisableDllImportResolver = true`, initializes ORT, then registers an
external resolver. Verifies no `InvalidOperationException` is thrown,
proving ORT correctly skipped its own registration.