Injecting information into type converters, etc, on request

21 views
Skip to first unread message

Michael Powell

unread,
Sep 8, 2016, 6:51:15 PM9/8/16
to AutoMapper-users
Hello,

I'd like to do something like this:

IMapperConfiguration mapperCfg = /* ... */

IMapper mapper = mapperCfg.CreateMapper();

// Possibly: cfg being the IMapperConfiguration, e being a TypeConverterRequiredEventArgs
mapper.TypeConverterRequired += (cfg, e) =>
{
    if (e.RequestedConverterType == typeof(MyTypeConverter)
    {
        // i.e. if done from a Controller where an Identity User is available
        e.Converter = new MyTypeConverter(this.User);
    }
};

Basically, I've got a type converter which I need to inject some details into, such as User Identity, in order to make decisions based on his/her Claims.

The alternative is brutal logic in the controller, which is what I'm trying to avoid much of. Additionally, the conversions are not different enough to justify a whole other type converter, per se; just a strategic decision here or there whether to convert a property one way or another. This kind of thing. I would if I had to, but it's overkill and potentially confounding to the API.

I haven't looked at the interfaces closely, yet, but I'm headed this direction. Is it possible?

Thanks!

Regards,

Michael Powell

Michael Powell

unread,
Sep 8, 2016, 7:06:35 PM9/8/16
to automapp...@googlegroups.com
On Thu, Sep 8, 2016 at 6:51 PM, Michael Powell <mwpow...@gmail.com> wrote:
> Hello,
>
> I'd like to do something like this:
>
> IMapperConfiguration mapperCfg = /* ... */
>
> IMapper mapper = mapperCfg.CreateMapper();
>
> // Possibly: cfg being the IMapperConfiguration, e being a
> TypeConverterRequiredEventArgs
> mapper.TypeConverterRequired += (cfg, e) =>
> {
> if (e.RequestedConverterType == typeof(MyTypeConverter)
> {
> // i.e. if done from a Controller where an Identity User is
> available
> e.Converter = new MyTypeConverter(this.User);
> }
> };
>
> Basically, I've got a type converter which I need to inject some details
> into, such as User Identity, in order to make decisions based on his/her
> Claims.
>
> The alternative is brutal logic in the controller, which is what I'm trying
> to avoid much of. Additionally, the conversions are not different enough to
> justify a whole other type converter, per se; just a strategic decision here
> or there whether to convert a property one way or another. This kind of
> thing. I would if I had to, but it's overkill and potentially confounding to
> the API.

Another option might be to pass the details in via view model on the
"left" (input) side. Mulling that one over a bit...

> I haven't looked at the interfaces closely, yet, but I'm headed this
> direction. Is it possible?
>
> Thanks!
>
> Regards,
>
> Michael Powell
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "AutoMapper-users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/automapper-users/zsv5d0kRNyE/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> automapper-use...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Michael Powell

unread,
Sep 8, 2016, 7:25:45 PM9/8/16
to AutoMapper-users


On Thursday, September 8, 2016 at 7:06:35 PM UTC-4, Michael Powell wrote:
On Thu, Sep 8, 2016 at 6:51 PM, Michael Powell <mwpow...@gmail.com> wrote:
> Hello,
>
> I'd like to do something like this:
>
> IMapperConfiguration mapperCfg = /* ... */
>
> IMapper mapper = mapperCfg.CreateMapper();
>
> // Possibly: cfg being the IMapperConfiguration, e being a
> TypeConverterRequiredEventArgs
> mapper.TypeConverterRequired += (cfg, e) =>
> {
>     if (e.RequestedConverterType == typeof(MyTypeConverter)
>     {
>         // i.e. if done from a Controller where an Identity User is
> available
>         e.Converter = new MyTypeConverter(this.User);
>     }
> };
>
> Basically, I've got a type converter which I need to inject some details
> into, such as User Identity, in order to make decisions based on his/her
> Claims.
>
> The alternative is brutal logic in the controller, which is what I'm trying
> to avoid much of. Additionally, the conversions are not different enough to
> justify a whole other type converter, per se; just a strategic decision here
> or there whether to convert a property one way or another. This kind of
> thing. I would if I had to, but it's overkill and potentially confounding to
> the API.

Another option might be to pass the details in via view model on the
"left" (input) side. Mulling that one over a bit...

Looks like I could do some gymnastics between an intermediate view model and using mapper options to expose BeforeMap and/or AfterMap. That should be sufficient to pass the details into the mapper via the view model input.

> I haven't looked at the interfaces closely, yet, but I'm headed this
> direction. Is it possible?
>
> Thanks!
>
> Regards,
>
> Michael Powell
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "AutoMapper-users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/automapper-users/zsv5d0kRNyE/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to

Michael Powell

unread,
Sep 9, 2016, 11:47:09 AM9/9/16
to AutoMapper-users


On Thursday, September 8, 2016 at 7:25:45 PM UTC-4, Michael Powell wrote:


On Thursday, September 8, 2016 at 7:06:35 PM UTC-4, Michael Powell wrote:
On Thu, Sep 8, 2016 at 6:51 PM, Michael Powell <mwpow...@gmail.com> wrote:
> Hello,
>
> I'd like to do something like this:
>
> IMapperConfiguration mapperCfg = /* ... */
>
> IMapper mapper = mapperCfg.CreateMapper();
>
> // Possibly: cfg being the IMapperConfiguration, e being a
> TypeConverterRequiredEventArgs
> mapper.TypeConverterRequired += (cfg, e) =>
> {
>     if (e.RequestedConverterType == typeof(MyTypeConverter)
>     {
>         // i.e. if done from a Controller where an Identity User is
> available
>         e.Converter = new MyTypeConverter(this.User);
>     }
> };
>
> Basically, I've got a type converter which I need to inject some details
> into, such as User Identity, in order to make decisions based on his/her
> Claims.
 
This is a guess on my part, but I could be wrong. Is there another, better way to connect the Identity User with a type converter?

    var data = _mapper.Map<IEnumerable<Data>, string>(rosters, opts => opts.ConstructServicesUsing(t =>
    {
        if (t == typeof(MyTypeConverter))
        {
            var converted = new MyTypeConverter {User = this.IdentityUser};
            return converted;
        }
        return null;
    }));

Jimmy Bogard

unread,
Sep 9, 2016, 12:44:52 PM9/9/16
to automapper-users
Hmmm. Can you go from the items context instead? That's how I imagined getting runtime information to the mapper extensions (value resolvers, type converters etc).

--
You received this message because you are subscribed to the Google Groups "AutoMapper-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to automapper-users+unsubscribe@googlegroups.com.

Michael Powell

unread,
Sep 9, 2016, 12:53:09 PM9/9/16
to automapp...@googlegroups.com
On Fri, Sep 9, 2016 at 12:44 PM, Jimmy Bogard <jimmy....@gmail.com> wrote:
> Hmmm. Can you go from the items context instead? That's how I imagined
> getting runtime information to the mapper extensions (value resolvers, type
> converters etc).

I see an Items dictionary as part of the BeforeMap/AfterMap options.
But, how is that conveyed to my TypeConverter? For now, an
intermediate view model seems to be sufficient, but if there's a
better way, I'm open to suggestions. Remember, my goals include making
User-based Claims decisions within the Type conversion itself.
>>>> > automapper-use...@googlegroups.com.
>>>> > For more options, visit https://groups.google.com/d/optout.
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "AutoMapper-users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to automapper-use...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "AutoMapper-users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/automapper-users/zsv5d0kRNyE/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> automapper-use...@googlegroups.com.

Michael Powell

unread,
Sep 9, 2016, 1:20:57 PM9/9/16
to automapp...@googlegroups.com
On Fri, Sep 9, 2016 at 12:53 PM, Michael Powell <mwpow...@gmail.com> wrote:
> On Fri, Sep 9, 2016 at 12:44 PM, Jimmy Bogard <jimmy....@gmail.com> wrote:
>> Hmmm. Can you go from the items context instead? That's how I imagined
>> getting runtime information to the mapper extensions (value resolvers, type
>> converters etc).
>
> I see an Items dictionary as part of the BeforeMap/AfterMap options.
> But, how is that conveyed to my TypeConverter? For now, an
> intermediate view model seems to be sufficient, but if there's a
> better way, I'm open to suggestions. Remember, my goals include making
> User-based Claims decisions within the Type conversion itself.

This may be a question of upgrading to a later version. I am currently
on 4.2.1, and using the generic AutoMapper TypeConverter. However,
these seem to have been removed. Now using
System.ComponentModel.TypeConverter. How come the change? What is the
path forward?

Michael Powell

unread,
Sep 9, 2016, 1:23:04 PM9/9/16
to automapp...@googlegroups.com
On Fri, Sep 9, 2016 at 1:20 PM, Michael Powell <mwpow...@gmail.com> wrote:
> On Fri, Sep 9, 2016 at 12:53 PM, Michael Powell <mwpow...@gmail.com> wrote:
>> On Fri, Sep 9, 2016 at 12:44 PM, Jimmy Bogard <jimmy....@gmail.com> wrote:
>>> Hmmm. Can you go from the items context instead? That's how I imagined
>>> getting runtime information to the mapper extensions (value resolvers, type
>>> converters etc).
>>
>> I see an Items dictionary as part of the BeforeMap/AfterMap options.
>> But, how is that conveyed to my TypeConverter? For now, an
>> intermediate view model seems to be sufficient, but if there's a
>> better way, I'm open to suggestions. Remember, my goals include making
>> User-based Claims decisions within the Type conversion itself.
>
> This may be a question of upgrading to a later version. I am currently
> on 4.2.1, and using the generic AutoMapper TypeConverter. However,
> these seem to have been removed. Now using
> System.ComponentModel.TypeConverter. How come the change? What is the
> path forward?

Another observation, TypeConverter has a public void
Convert(ResolutionContext), but which is not abstract, much less
virtual, and the Context is not exposed to inherited classes. So,
apparently your vision for the mapper did not follow through?

As I said, view model is sufficient for now, but if there's a better
way, and/or a path forward with these type converters, open to
suggestions what that is.

Jimmy Bogard

unread,
Sep 9, 2016, 6:25:02 PM9/9/16
to automapp...@googlegroups.com
Yep, the class was removed in favor of the interface. The class was no longer necessary.

Michael Powell

unread,
Sep 9, 2016, 6:50:03 PM9/9/16
to automapp...@googlegroups.com
On Fri, Sep 9, 2016 at 6:24 PM, Jimmy Bogard <jimmy....@gmail.com> wrote:
> Yep, the class was removed in favor of the interface. The class was no
> longer necessary.

Thanks, I may have a look, but an upgrade is not high on my priority
list right now. In the meantime, how do you figure it was unnecessary?

Jimmy Bogard

unread,
Sep 9, 2016, 6:51:16 PM9/9/16
to automapp...@googlegroups.com
Well I'd rather not have both a base class and interface. Just have an interface.

Michael Powell

unread,
Sep 9, 2016, 6:56:39 PM9/9/16
to automapp...@googlegroups.com
On Fri, Sep 9, 2016 at 6:51 PM, Jimmy Bogard <jimmy....@gmail.com> wrote:
> Well I'd rather not have both a base class and interface. Just have an
> interface.

Which is where we find the ResolutionContext.

TDestination Convert(TSource source, TDestination destination,
ResolutionContext context);

Question, destination is there, whether user-provided or mapper-provider?

Got it. Thanks!

Jimmy Bogard

unread,
Sep 9, 2016, 7:11:48 PM9/9/16
to automapp...@googlegroups.com
Ohhhhh I don't remember. I want to say user provided, because with a type converter I wouldn't try to build the destination.

Unless it's a sub property.

Michael Powell

unread,
Sep 9, 2016, 7:21:59 PM9/9/16
to automapp...@googlegroups.com
On Fri, Sep 9, 2016 at 7:11 PM, Jimmy Bogard <jimmy....@gmail.com> wrote:
> Ohhhhh I don't remember. I want to say user provided, because with a type
> converter I wouldn't try to build the destination.

No, not necessarily.

In v4.2.1, we are returning the destination. In one case, I am
actually returning the then-converted JSON string representation,
after having built the Json Linq object tree. That's one use case.

In another use case, I don't use type converter, but the ForMember,
and other methods, and use it to "merge" view model data into an
already-existing destination.
Reply all
Reply to author
Forward
0 new messages