Skip to content

MapFrom variable 'src' of type 'Xyz' referenced from scope '', but it is not defined #1778

@adam-resdiary

Description

@adam-resdiary

I've having an issue where I have a mapping using MapFrom, where the expression passes the object being mapped into a method call. I'm not quite sure how to explain this properly, but I've managed to create a set of tests that highlight the issue.

I've tested this against the MyGet alpha version of AutoMapper.

So say I have the following classes:

public interface IDateProvider
{
	DateTime CurrentRestaurantTime(Restaurant restaurant);
}

public class Result
{
	public Booking Booking { get; set; }
}

public class Restaurant
{
}

public class Booking
{
	public Restaurant Restaurant { get; set; }

	public int? CalculateTotal(DateTime currentTime)
	{
		return null;
	}
}

public class ResultDto
{
	public BookingDto Booking { get; set; }
}

public class BookingDto
{
	public int? Total { get; set; }
}

And I create the following mapping:

var mapperConfiguration = new MapperConfiguration(cfg =>
{
	cfg.CreateMap<Result, ResultDto>();
	cfg.CreateMap<Booking, BookingDto>()
		.ForMember(d => d.Total,
			o => o.MapFrom(b => b.CalculateTotal(_dateProvider.CurrentRestaurantTime(b.Restaurant))));
});

When I try to map from a Result to a ResultDto, I get the following exception:

System.InvalidOperationException : variable 'src' of type 'AutoMapperRepros.Class1+Booking' referenced from scope '', but it is not defined
   at System.Linq.Expressions.Compiler.VariableBinder.Reference(ParameterExpression node, VariableStorageKind storage)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitParameter(ParameterExpression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitMember(MemberExpression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitArguments(IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitArguments(IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitTry(TryExpression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitTry(TryExpression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitConditional(ConditionalExpression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitTry(TryExpression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitBlock(BlockExpression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitConditional(ConditionalExpression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Compiler.VariableBinder.Bind(LambdaExpression lambda)
   at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator)
   at AutoMapper.MapperConfiguration.CreateMapperFuncs(MapRequest mapRequest)
   at AutoMapper.LockingConcurrentDictionary`2.<>c__DisplayClass2_1.<.ctor>b__1()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at AutoMapper.MapperConfiguration.GetUntypedMapperFunc(MapRequest mapRequest)
   at AutoMapper.Mapper.AutoMapper.IMapper.Map[TDestination](Object source)
   at AutoMapperRepros.Class1.FailingMapping() in C:\Users\AdamConnelly\github.com\adam-resdiary\AutoMapperRepros\AutoMapperRepros\Class1.cs:line 40

I can work around this by extracting the lambda into a separate method instead of writing it inline.

Here's a link to a gist with one test that fails, highlighting the issue, and another test that passes showing the workaround: https://gist.github.com/adam-resdiary/137396c167c03cda15d42816d953461b

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions