LuckyPennySoftware/AutoMapper · error · InvalidOperationException

Type '{objectConstructorType.Name}' does not implement IDest

Error message

Type '{objectConstructorType.Name}' does not implement IDestinationFactory<{SourceType.Name}, {DestinationType.Name}>

What it means

ConstructUsingObjectConstructor(Type) wires destination construction to a factory object invoked as factory.Construct(source, context). It requires the supplied type to implement IDestinationFactory<TSource,TDestination> with the exact generic arguments of the map; expectedInterface.IsAssignableFrom(objectConstructorType) is checked and the throw names the required closed interface. The Construct method is then reflected off that interface.

Source

Thrown at src/AutoMapper/TypeMap.cs:268

    public void IncludeBaseTypes(TypePair baseTypes)
    {
        CheckDifferent(baseTypes);
        Details.IncludeBaseTypes(baseTypes);
    }
    public void AddBeforeMapAction(LambdaExpression beforeMap) => Details.AddBeforeMapAction(beforeMap);
    public void AddAfterMapAction(LambdaExpression afterMap) => Details.AddAfterMapAction(afterMap);
    public void AddValueTransformation(ValueTransformerConfiguration config) => Details.AddValueTransformation(config);
    public void ConstructUsingServiceLocator() => CustomCtorFunction = Lambda(ServiceLocator(DestinationType));
    public void ConstructUsingObjectConstructor(Type objectConstructorType)
    {
        var srcParam = Parameter(SourceType);
        var ctxParam = Parameter(typeof(ResolutionContext));

        var constructorInstance = ServiceLocator(objectConstructorType);
        var expectedInterface = typeof(IDestinationFactory<,>).MakeGenericType(SourceType, DestinationType);
        if (!expectedInterface.IsAssignableFrom(objectConstructorType))
        {
            throw new InvalidOperationException($"Type '{objectConstructorType.Name}' does not implement IDestinationFactory<{SourceType.Name}, {DestinationType.Name}>");
        }
        var constructMethod = expectedInterface.GetMethod("Construct") ??
            throw new InvalidOperationException($"IDestinationFactory<{SourceType.Name}, {DestinationType.Name}> does not define a 'Construct' method.");

        var callExpression = Call(
            Convert(constructorInstance, expectedInterface),
            constructMethod,
            srcParam, ctxParam
        );

        CustomCtorFunction = Lambda(callExpression, srcParam, ctxParam);
    }
    internal LambdaExpression CreateMapperLambda(IGlobalConfiguration configuration) =>
        Types.ContainsGenericParameters ? null : new TypeMapPlanBuilder(configuration, this).CreateMapperLambda();
    private PropertyMap GetPropertyMap(string name)
    {
        if (_propertyMaps == null)
        {

View on GitHub (pinned to dfa6dd587c)

Solutions

  1. Make the factory implement IDestinationFactory<TSource, TDestination> with the exact same type arguments as the CreateMap<TSource,TDestination>.
  2. Verify up front: typeof(IDestinationFactory<S,D>).IsAssignableFrom(typeof(Factory)).
  3. If you do not need a reusable factory, use ConstructUsing((s, ctx) => new D(...)) for ad-hoc construction instead.
  4. Double-check you are passing the factory type, not the destination type.

Example fix

// before
public class DFactory : IDestinationFactory<Dest, Source> { ... } // wrong arg order
CreateMap<Source, Dest>().ConstructUsingObjectConstructor(typeof(DFactory)); // throws

// after
public class DFactory : IDestinationFactory<Source, Dest>
{
    public Dest Construct(Source source, ResolutionContext context) => new Dest(source.Id);
}
CreateMap<Source, Dest>().ConstructUsingObjectConstructor(typeof(DFactory));
Defensive patterns

Strategy: type-guard

Validate before calling

var expected = typeof(IDestinationFactory<,>).MakeGenericType(typeof(TSrc), typeof(TDst));
if (!expected.IsAssignableFrom(typeof(TFactory)))
{
    throw new InvalidOperationException(
        $"{typeof(TFactory)} must implement IDestinationFactory<{typeof(TSrc).Name}, {typeof(TDst).Name}.");
}

cfg.CreateMap<TSrc, TDst>().ConstructUsingObjectConstructor(typeof(TFactory));

Type guard

static bool ImplementsFactoryFor<TSrc, TDst>(Type factoryType) =>
    typeof(IDestinationFactory<TSrc, TDst>).IsAssignableFrom(factoryType);

Try / catch

try { cfg.CreateMap<S, D>().ConstructUsingObjectConstructor(typeof(F)); }
catch (InvalidOperationException ex) when (ex.Message.Contains("does not implement IDestinationFactory"))
{
    // correct the generic arguments on the factory interface, then retry
}

Prevention

When it happens

Trigger: cfg.CreateMap<S,D>().ConstructUsingObjectConstructor(typeof(F)) where F does not implement IDestinationFactory<S,D> (generic args swapped to IDestinationFactory<D,S>, implements a different/base interface, or the destination type itself is passed instead of a factory).

Common situations: Swapped generic arguments on the factory interface; factory implementing only a non-generic marker interface; passing typeof(D) (the destination) by mistake; renaming types so the closed interface no longer matches.

Related errors


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