dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'resourceFactory')

Error message

Value cannot be null. (Parameter 'resourceFactory')

What it means

Using ties a disposable resource's lifetime to the enumeration of a sequence: resourceFactory obtains the resource and it is disposed when enumeration completes. The factory delegate itself is validated eagerly, so passing a null resourceFactory throws ArgumentNullException naming `resourceFactory`.

Solutions

  1. Supply a real factory lambda: `Using(() => File.OpenText(path), reader => ...`.
  2. Fix the DI/registry lookup so the factory delegate is registered and resolved.
  3. Guard optional hooks: `factory ?? DefaultResourceFactory`.
  4. If no resource is needed, don't call Using — just build the sequence directly.

Example fix

// before
var seq = Using<int, FileStream>(config.ReaderFactory, fs => Read(fs));
// after
var seq = Using<int, FileStream>(() => File.OpenRead(config.Path), fs => Read(fs));
Defensive patterns

Strategy: validation

Validate before calling

if (resourceFactory is null) throw new ArgumentNullException(nameof(resourceFactory));

Type guard

static bool CanAcquire<TResource>(Func<TResource> f) where TResource : IDisposable => f is not null;

Try / catch

try { var seq = Using(resFactory, enumFactory); }
catch (ArgumentNullException ex) when (ex.ParamName == "resourceFactory") { /* fix DI/registration */ }

Prevention

When it happens

Trigger: Calling `Using<TSource, IDisposable>(null, r => ...)` — e.g. forwarding a nullable delegate field, or a misconfigured factory method reference that is null at runtime.

Common situations: Dependency-injection scenarios where the resource factory is resolved from a container/registry that returned null, or dynamically composed pipelines where optional delegate hooks are left unset.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/cbd42584c95f5873. Report an issue: GitHub.

Appendix: source

Thrown at Ix.NET/Source/System.Interactive/System/Linq/Operators/Using.cs:23

using System.Collections.Generic;

namespace System.Linq
{
    public static partial class EnumerableEx
    {
        /// <summary>
        /// Generates a sequence that's dependent on a resource object whose lifetime is determined by the sequence usage
        /// duration.
        /// </summary>
        /// <typeparam name="TSource">Source element type.</typeparam>
        /// <typeparam name="TResource">Resource type.</typeparam>
        /// <param name="resourceFactory">Resource factory function.</param>
        /// <param name="enumerableFactory">Enumerable factory function, having access to the obtained resource.</param>
        /// <returns>Sequence whose use controls the lifetime of the associated obtained resource.</returns>
        public static IEnumerable<TSource> Using<TSource, TResource>(Func<TResource> resourceFactory, Func<TResource, IEnumerable<TSource>> enumerableFactory) where TResource : IDisposable
        {
            if (resourceFactory == null)
                throw new ArgumentNullException(nameof(resourceFactory));
            if (enumerableFactory == null)
                throw new ArgumentNullException(nameof(enumerableFactory));

            return UsingCore(resourceFactory, enumerableFactory);
        }

        private static IEnumerable<TSource> UsingCore<TSource, TResource>(Func<TResource> resourceFactory, Func<TResource, IEnumerable<TSource>> enumerableFactory) where TResource : IDisposable
        {
            using var res = resourceFactory();

            foreach (var item in enumerableFactory(res))
            {
                yield return item;
            }
        }
    }
}

View on GitHub (pinned to 94b5d5ab91)