I am attempting to clean up a lot of my code which relates to creating web service requests, and mapping back and forth between view models and data transfer objects. I currently have the following setup in my code:
public class Request1 : IRequest<Type1>
{
    public Type1 Data { get; set; }
}
public interface IRequest<T>
{
    T Data { get; set; }
}
public class Type1
{
    string Account {get; set; }
    ...
}
public static class Mapper 
{ 
    public static TOut CreateRequest<TOut, TIn>(TIn data) where TIn : IRequest<TIn>, new() 
    {
        var request = new TOut();
        request.Data = data;
        return request;
    }
}
The above enables me to use generics to create the Request1 object by passing in the data really simply.
var model = new ViewModel();
var data = Mapper.mapFromViewModel(model);
var request = Mapper.CreateRequest<Request1,Type1>(data);
This is GREAT in my opinion, however it has one flaw.
The data I pass in has to be of the dto type (Type1) in the request. What I would like to do is pass in the data in its raw form, so in the UI I would be passing in the view model data, and the type of Request I want. The method would work out the mapping between the view model and the dto type, and then create the request for me.
So if I use a bit of AutoMapper to handle the mapping between the view model and the dto type I can get to this:
public TOut CreateRequest2<TOut, TDto, TModelIn>(TModelIn data) 
    where TOut : IRequest<TDto>, new()
{
    var request = new TOut();
    request.Data = Map<TModelIn, TDto>(data);
    return request;
}
Which I can use like this:
var model = new ViewModel();
var request = Mapper.CreateRequest2<Request1,Type1,ViewModel>(model);
This is almost there... but this is where I hit the wall of my knowledge.
I would like to be able to cut the TDto requirement from the call, so the caller only has to know about the Request, and the ViewModel types.
Something like:
public TOut CreateRequest3<TOut, TModelIn>(TModelIn data) 
{
    // Cast? the TOut to IRequest<>
    // Extract the TDto type from the IRequest<> object and 
    // pass the TDto type into the method I created earlier.
    return CreateRequest2<TOut,TDto,TModelIn>(data);
}
Does anyone know if this can be achieved?
The upside of this is to remove the need for my UI code to know what DTO is required on a message, and let that be handled by automapper based on the view model it is given.
UPDATE: So following suggestions by @EpicSam I now have the following that works:
    public TOut CreateRequest3<TOut, TModelIn>(TModelIn data) where TOut : class, new()
    {
        var interfaces = typeof(TOut).GetInterfaces().FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IRequest<>));
        var dtoType = interfaces?.GenericTypeArguments.FirstOrDefault();
        var result =  typeof(Mapper)
            .GetMethod(nameof(Mapper.CreateRequest))
            .MakeGenericMethod(typeof(TOut), dtoType, typeof(TModelIn))
            .Invoke(this, new object[ ] {data});
        return result as TOut;
    }
This is ugly, but is ok, as its only ever written once. But.. what other things do I need to know about this code. As it uses reflection, is it going to hammer my performance, or should I not even worry about it....
UPDATE 2: The reflection code is about 3x slower than the original code I posted. So even though I could choose to make my code nicer and cleaner, I'll opt to keep it as it is, and work more efficiently.
 
     
     
    