Esteban
Esteban

Reputation: 3127

Custom generic DTO Assembler

I'm trying to create a method which can be used like this:

Assembler.CreateTransfer(i);

As for my models is like this:

public abstract class UserBase {
    public long UserId { get; set; }
    public string Username { get; set; }
}

public class UserTransfer : UserBase, ITransferObject { }

public partial class User : UserTransfer, IModelBase, IDomainObject {
    public User() {
        Roles = new List<Role>();
    }

    public virtual ICollection<Role> Roles { get; set; }
}

So far, I've accomplished this:

public static TTransfer CreateTransfer<TTransfer, TDomain>(TDomain d)
        where TTransfer : ITransferObject
        where TDomain : IDomainObject
    { ... }

The problem comes when I try create the dto without specifying any type:

CreateTransfer(d);

Of course I've added an overload for this task and I hope I can magically accomplish the following:

public static ITransferObject CreateTransfer(IDomainObject d) {
    // do magic
    return CreateTransfer<transfer, domain>(d);
}

But in the real world, this is as far as I could get:

public static ITransferObject CreateTransfer(IDomainObject d) {
    var dType = d.GetType();

    var assemblyName = dType.Assembly.FullName;

    var domainName = dType.FullName;
    var transferName = domainName + "Transfer";

    var domain = Activator.CreateInstance(assemblyName, domainName).UnWrap();
    var transfer = Activator.CreateInstance(assemblyName, transferName).UnWrap();

    return CreateTransfer< ?, ?>(d); // Problem
}

The main question is: Is there any way to be able to call CreateTransfer<domain, transfer>(d)? Any help will be appreciated.

Upvotes: 0

Views: 864

Answers (1)

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174447

You can use reflection to call the generic method.

Something like this:

var method = typeof(ClassThatDefinesCreateTransfer)
                 .GetMethods()
                 .Single(x => x.Name == "CreateTransfer" &&
                             x.IsGenericMethodDefinition)
                 .MakeGenericMethod(dType, transferType);
return (ITransferObject )method.Invoke(null, new object[] { d });

You probably want to cache at least the result of typeof(ClassThatDefinesCreateTransfer).GetMethods().

Upvotes: 1

Related Questions