Frage

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

Assembler.CreateTransfer(i);
  • i is an item inside a dynamic collection.
  • i is a domain object.
  • CreateTransfer() should return an instance of i type + Transfer (if my domain object is User, then it should return an instance of UserTransfer.

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
    { ... }
  • This works, because I know the type of TTransfer and TDomain.
  • And I can call it like: CreateTransfer<UserTransfer, User>(d).

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
}
  • Both domain and transfer objects are being created correctly.

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

War es hilfreich?

Lösung

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().

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top