{"record":{"id":"284138216e5f75c4","repo":"LuckyPennySoftware/AutoMapper","slug":"only-interfaces-can-be-proxied-destinationtype","errorCode":null,"errorMessage":"Only interfaces can be proxied. {DestinationType}","messagePattern":"Only interfaces can be proxied\\. (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/AutoMapper/Configuration/TypeMapConfiguration.cs","lineNumber":383,"sourceCode":"            IgnoreDestinationMember(property);\n        }\n        return this as TMappingExpression;\n    }\n    public TMappingExpression IgnoreAllSourcePropertiesWithAnInaccessibleSetter()\n    {\n        foreach (var property in PropertiesWithAnInaccessibleSetter(SourceType))\n        {\n            ForSourceMemberCore(property, options => options.DoNotValidate());\n        }\n        return this as TMappingExpression;\n    }\n    private static IEnumerable<PropertyInfo> PropertiesWithAnInaccessibleSetter(Type type) => type.GetRuntimeProperties().Where(p => p.GetSetMethod() == null);\n    public void ConvertUsing(Expression<Func<TSource, TDestination>> mappingFunction) => SetTypeConverter(new ExpressionTypeConverter(mappingFunction));\n    public TMappingExpression AsProxy()\n    {\n        if (!DestinationType.IsInterface)\n        {\n            throw new InvalidOperationException(\"Only interfaces can be proxied. \" + DestinationType);\n        }\n        TypeMapActions.Add(tm => tm.AsProxy());\n        return this as TMappingExpression;\n    }\n}","sourceCodeStart":365,"sourceCodeEnd":388,"githubUrl":"https://github.com/LuckyPennySoftware/AutoMapper/blob/dfa6dd587c5854b4beee5934beb39ba6e9569b84/src/AutoMapper/Configuration/TypeMapConfiguration.cs#L365-L388","documentation":"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.","triggerScenarios":"Calling .AsProxy() on a CreateMap<TSource, TDestination>() where TDestination is a concrete class, struct, or abstract class rather than an interface.","commonSituations":"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.","solutions":["Define an interface for the destination contract and map to that interface, then call AsProxy().","If you need a concrete destination, map to a concrete class with a public constructor instead of using AsProxy."],"exampleFix":"// before — destination is a class\npublic class Dest { public string Name { get; set; } }\nCreateMap<Source, Dest>().AsProxy();\n\n// after — destination is an interface\npublic interface IDest { string Name { get; set; } }\nCreateMap<Source, IDest>().AsProxy();","handlingStrategy":"validation","validationCode":"// Check destination is an interface before calling AsProxy\nif (!typeof(TDestination).IsInterface)\n    throw new InvalidOperationException($\"{typeof(TDestination).Name} is not an interface. AsProxy only works with interfaces.\");","typeGuard":"// Compile-time guard via generic constraint\n// Only allow interface destinations for AsProxy usage\nstatic void ConfigureProxyMap<TSource, TDestination>()\n    where TDestination : class  // ideally also an interface\n{\n    if (!typeof(TDestination).IsInterface)\n        throw new InvalidOperationException(\"AsProxy requires an interface destination type.\");\n}","tryCatchPattern":null,"preventionTips":["Only call AsProxy when the destination type is an interface.","Define interfaces for your DTO contracts and map to those when you need proxy behavior.","Use a runtime IsInterface check in shared helper code to fail fast with a clear message."],"tags":["configuration","proxy","interface","mapping"],"backgroundTag":null,"analyzedSha":"dfa6dd587c5854b4beee5934beb39ba6e9569b84","analyzedAt":"2026-08-13T19:56:33.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}