Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass value to a custom ValueResolver?

Tags:

c#

automapper

I'm struggling with the format for passing in a value to a custom ValueResolver. I am basically trying to convert an Int to and Object based on my ViewModel. However, I cannot get it to pass it the value to my ValueResolver

I have the following Custom ValueResolver:

public class CustomResolver : ValueResolver<CreateContainerViewModel, Container>
{ 
    private int id = 0;

    public CustomResolver(int? sourceId)
    {
        if(sourceId.HasValue)
            id = sourceId.Value;
    }
    protected override Container ResolveCore(CreateContainerViewModel source)
    {
        if (id == 0) return null;
        else
        {
            ISession _session = DependencyResolver.Current.GetService<ISessionFactory>().GetCurrentSession();
            return _session.Get<Container>(id);
        }
    }
}

It works fine when I create the map using a hard coded int like the following code

Mapper.CreateMap<CreateContainerViewModel, Container>()
.ForMember(a => a.CurrentContainer, opt => opt.ResolveUsing(src => new CustomResolver(33)));

but it isn't working (throwing mapping exception) when I try and get the value from my viewmodel

Mapper.CreateMap<CreateContainerViewModel, Container>()
            .ForMember(dest => dest.CurrentContainer, opt => opt.MapFrom(src => new CustomResolver(src.CurrentContainerId)));

Can anyone point me in the direction of the correct syntax for passing in a value to a custom ValueResolver?

Thanks

UPDATE:

basically trying to write something like this:

  public class IdToObjectResolver<T> : ValueResolver<int, T> where T : class
{ 
    private ISession _session;
    private int id;
    public IdToObjectResolver(Nullable<int> sourceId)
    {
        _session = DependencyResolver.Current.GetService<ISessionFactory>().GetCurrentSession();
        if(sourceId.HasValue)
            id = sourceId.Value;
    }

    protected override T ResolveCore(int source)
    {
        return _session.Get<T>(source);
    }
}

This code doesnt currently make sense, but just trying to get a way of passing in the int...

like image 885
TomL Avatar asked Dec 31 '25 00:12

TomL


1 Answers

If I understand correctly, I think that you might be over complicating the ValueResolver a bit. As you can see, the entire CreateContainerViewModel class is send in the ResolveCore method in the ValueResolver. That will be the entire source object with values.

Therefore, you should be able to pull the id value from the source object by using this mapping: opt.ResolveUsing(src => new CustomResolver()). (with no constructor arg).

Hope this helps.

EDIT:

My Test:

        [TestMethod]
        public void TestMethod1()
        {
            Mapper.CreateMap<CreateContainerViewModel, Container>()
                .ForMember(a => a.CurrentContainer, opt => opt.ResolveUsing<CustomResolver>());


            var source = new CreateContainerViewModel()
            {
                ID = 3
            };

            var destination = new Container();

            Mapper.Map(source, destination);

            Assert.AreEqual(destination.CurrentContainer.ID, 3);

        }

CustomResolver:

public class CustomResolver : ValueResolver<CreateContainerViewModel, Container>
{
    protected override Container ResolveCore(CreateContainerViewModel source)
    {

            return new Container() { ID = source.ID };  
    }
}
like image 141
Davin Tryon Avatar answered Jan 02 '26 14:01

Davin Tryon