When using a lambda you can pass values that are seen when you are defining the lambda; this is called closure and allows your variables to be lifted into the lambda. For example
void call_lambda(Func<int> f)
{
Console.WriteLine("Int value is " + f());
}
/* ... */
void lambda_caller()
{
int i = 150;
call_lambda(() => i);
}
would print the correct value of i
even though it doesn't exist in the scope of call_lambda
. The same thing happens for any lambda; variables in the scope where they are defined can be used for definition, and will be resolved at execution.
In your case, you can define your connection outside of your mapping and pass it into the lambda for execution:
var dbConnection = createConnection();
AutoMapper.Mapper.CreateMap().ForMember(dest => dest.deviceColor, opt => opt.ResolveUsing((source) => { return MyTools.GetDeviceColor(dbConnection, source.DeviceId); }));
However there is a catch; by lifting the variable into the lambda you don't surrender its control to the lambda. If you close the connection after defining your mapping the lambda can't execute since the connection it knows is closed. So I'd rather recommend wrapping the whole connection setup and query into the lambda in order to keep control over it. Inside the lambda you can setup any optimization you want to avoid hitting the DB at each mapping (caching for example) but you really shouldn't setup the connection outside of it.