AutoMapper with Dataset as parameter in profile

239 Views Asked by At

I have some problem when using AutoMapper. I searched everywhere I could but either I don't understand the solution (when no code is provided) or it doesn't apply to my situation.

I have my profile :

public class MyCustomProfile : Profile
{
    public MyCustomProfile()
    {
        CreateMap<DTO.Person, MyDataSet.PersonRow>();
    }
}

And I have my method :

public static void TestAutoMapper(DTO.Person p)
{
    if (Mapper.Instance == null)
    {
        Mapper.Initialize(cfg => cfg.AddProfile<MyCustomProfile>());
    }

    MyDataSet.PersonRow pr = Mapper.Map<MyDataSet.PersonRow>(p);
}

But my problem is : I need to add in my profile .ConstructUsing(p => dts.get_XYdataset().Person.NewPersonRow()); where dts is an instance of MyDataSet.

And I also need this instance of MyDataSet dts in the method TestAutoMapper(DTO.Person p) to save the result MyDataSet.PersonRow pr as the following :

dts.get_XYdataset().Person.AddPersonRow(pr)

But I don't know what to do. It works well if I put everything in the TestAutoMapper() method but of course it's not clean and I want to separate logics by creating a profile and calling it when initializing the mapper.

EDIT

So I modified my TestAutoMapper() method like this :

public static void TestAutoMapper(DTO.Person p)
{
    if (Mapper.Instance == null)
    {
        Mapper.Initialize(cfg => cfg.AddProfile<MyCustomProfile>());
    }

    using (MyDataSet dts = new MyDataSet())
    {
        MyDataSet.PersonRow pr = Mapper.Map<MyDataset.PersonRow>(p, opt => opt.Items["Dataset"] = dts);
        dts.get_XYdataset().Person.AddPersonRow(pr);
    }

Then I tried to follow the mini tuto about Custom Resolvers and implemented this class :

public class CustomResolver: IMemberValueResolver<object, object, MyDataSet, MyDataSet>
{
    public MyDataSet Resolve(object source, object destination, MyDataSet dts, MyDataSet dts2, ResolutionContext context)
    {
        if (dts != null)
        {
            return dts;
        }
        else if (dts2 != null)
        {
            return dts2;
        }
        return new MyDataSet();
    }
}

But I don't think this is okay. But well, nevermind I tried anyway. But now I'm stuck in my profile constructor in the CreateMap<DTO.Person, MyDataSet.PersonRow>() statement. How to get the Options.Items["Dataset"] in the .ConstructUsing() ?

Examples show about a CustomResolver about a member but how about specifying a constructor ?
It would be so perfect if I could do something like :
CreateMap<DTO.Person, MyDataSet.PersonRow>() .ConstructUsing(Options.Items["Dataset"].get_XYdataset().Person.NewPersonRow());

I know my need for help can be silly but I really don't understand even by reading the docs.

What do you think ?

Thanks,

Hellcat8

1

There are 1 best solutions below

0
Hellcat8 On

Okay finally it works with this code :

public static class PersonManager
{
    private static MapperConfiguration _config;
    private static IMapper _mapper;

    public static void TestAutoMapper(DTO.Person p)
    {
        if (_config == null)
        {
            _config = new MapperConfiguration(cfg => cfg.AddProfile<MyCustomProfile>());
        }

        if (_mapper == null)
        {
             _mapper = _config.CreateMapper();
        }

        using (MyDataSet dts = new MyDataSet())
        {
            XYdataset.PersonRow pr = _mapper.Map<XYdataset.PersonRow>(p, opt => opt.Items["Dataset"] = dts);
            dts.get_XYdataset().Person.AddPersonRow(pr);
        }
     }
 }

And I have my profile :

public class MyCustomProfile : Profile
{
    public MyCustomProfile()
    {
        CreateMap<DTO.Person, XYdataset.PersonRow>()  
             .ConstructUsing((source, resolutionContext) =>  
             (resolutionContext.Items["Dataset"] as MyDataSet)  
             .(get_XYdataset().Person.NewPersonRow());
    }
}