简体   繁体   中英

How can I expose a generic method with a dynamically data type?

I want to create a (kinda) fluent interface class for configuring a message with fields.

Let's say I have an Ack Message and an Admit Message and they have completely different fields. In the fluent configuration class I want to make sure that the length of a field is a certain length as well as other configurations.

So for instance I'd call:

IMessagingSystemConfiguration config = new MessagingSystemConfiguration();
config.AddMessage<Ack>().ValidateLength(x=>x.Body,25);
config.AddMessage<Admit>().ValidateLength(x=>x.Header,10);

The MessagingSystemConfiguration Class:

  public class MessagingSystemConfiguration : IMessagingSystemConfiguration
  {
    public MessageConfiguration AddMessage<T>() where T: IMessage
    {
      {
        return new MessageConfiguration(T.GetType());
      }
    }

   public class MessageConfiguration
   {
     private Type _messageType;
     public MessageConfiguration(Type messageType)
     {
        _messageType = messageType;
     }

    void ValidateLength(Expression<Func<T, object>> field, int length )where T: IField
    {

    }

}

I just wrote this so ignore the fact it might not compile. I want the "T" in ValidateLength to be of the dataType of the message I pass in so that I have access to "Body" for and Ack Message and "Header" for an Admit Message.

I can't use reflection because it's a property on the class that I want to access during compile time.

I could also change the method:

    void ValidateLength<T>(Expression<Func<T, object>> field, int length )where T: IField
    {

    }

and then call:

 config.AddMessage<Ack>().ValidateLength<Ack>(x=>x.Body,25);

but I already know the type of message from the AddMessage and it adds extra complexity to add another generic type to ValidateLength as it will always be whatever I pass to AddMessage.

Is there any way to do this?

Can't you make MessageConfiguration generic as well?

public class MessageConfiguration<T> where T: IField
{
    void ValidateLength(Expression<Func<T, object>> field, int length )
    {

    }

}

Then you create it like this:

public MessageConfiguration<T> AddMessage<T>() where T: IMessage, IField
{
  {
    return new MessageConfiguration<T>();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM