LuckyPennySoftware/AutoMapper · error · InvalidOperationException

Only interfaces can be proxied. {DestinationType}

Error message

Only interfaces can be proxied. {DestinationType}

What it means

Thrown by AsProxy() when the destination type is not an interface. AutoMapper's proxy generation uses System.Reflection.Emit to build a dynamic concrete class implementing the interface, including INotifyPropertyChanged support. It can only proxy interface types because it generates a class that implements them.

Source

Thrown at src/AutoMapper/Configuration/TypeMapConfiguration.cs:383

            IgnoreDestinationMember(property);
        }
        return this as TMappingExpression;
    }
    public TMappingExpression IgnoreAllSourcePropertiesWithAnInaccessibleSetter()
    {
        foreach (var property in PropertiesWithAnInaccessibleSetter(SourceType))
        {
            ForSourceMemberCore(property, options => options.DoNotValidate());
        }
        return this as TMappingExpression;
    }
    private static IEnumerable<PropertyInfo> PropertiesWithAnInaccessibleSetter(Type type) => type.GetRuntimeProperties().Where(p => p.GetSetMethod() == null);
    public void ConvertUsing(Expression<Func<TSource, TDestination>> mappingFunction) => SetTypeConverter(new ExpressionTypeConverter(mappingFunction));
    public TMappingExpression AsProxy()
    {
        if (!DestinationType.IsInterface)
        {
            throw new InvalidOperationException("Only interfaces can be proxied. " + DestinationType);
        }
        TypeMapActions.Add(tm => tm.AsProxy());
        return this as TMappingExpression;
    }
}

View on GitHub (pinned to dfa6dd587c)

Solutions

  1. Define an interface for the destination contract and map to that interface, then call AsProxy().
  2. If you need a concrete destination, map to a concrete class with a public constructor instead of using AsProxy.

Example fix

// before — destination is a class
public class Dest { public string Name { get; set; } }
CreateMap<Source, Dest>().AsProxy();

// after — destination is an interface
public interface IDest { string Name { get; set; } }
CreateMap<Source, IDest>().AsProxy();
Defensive patterns

Strategy: validation

Validate before calling

// Check destination is an interface before calling AsProxy
if (!typeof(TDestination).IsInterface)
    throw new InvalidOperationException($"{typeof(TDestination).Name} is not an interface. AsProxy only works with interfaces.");

Type guard

// Compile-time guard via generic constraint
// Only allow interface destinations for AsProxy usage
static void ConfigureProxyMap<TSource, TDestination>()
    where TDestination : class  // ideally also an interface
{
    if (!typeof(TDestination).IsInterface)
        throw new InvalidOperationException("AsProxy requires an interface destination type.");
}

Prevention

When it happens

Trigger: Calling .AsProxy() on a CreateMap<TSource, TDestination>() where TDestination is a concrete class, struct, or abstract class rather than an interface.

Common situations: Trying to proxy a concrete class to auto-fill read-only or init-only properties; misunderstanding that AsProxy generates an implementation for an interface contract.

Related errors


AI-assisted analysis of LuckyPennySoftware/AutoMapper@dfa6dd587c (2026-08-13). Data as JSON: /api/errors/284138216e5f75c4. Report an issue: GitHub.