0

1. I have a function DoSomeService with object response as parameter. response are different classes the internal code decides which one to use dynamically at runtime.

2. I have a generic Fluent Validator< T> that takes in the type of a response class, then validates it.

Now, I can do type checking one by one:

public override void DoSomeService(object response) {
    object validator = null;
    if (response.GetType()==typeof(TypeA_Response)) validator= new Validator<TypeA_Response>();
    if (response.GetType()==typeof(TypeB_Response)) validator= new Validator<TypeB_Response>();
    if (response.GetType()==typeof(TypeC_Response)) validator= new Validator<TypeC_Response>();
    //......
    if (response.GetType()==typeof(TypeX_Response)) validator= new Validator<TypeX_Response>();
        if (validator.IsValid) {
        //do more stuff ...
    }
}

But that is not nice, especially when I have many responses. I want something short and generic.

//response could be TypeA_Response, TypeB_Response, TypeX_Response
public override void DoSomeService(object response) {
    var validator = new Validator<T>();
    if (validator.IsValid) {
        //do more stuff ...
    }
}

Of course, this won't work because I need to define T for Fluent Validator. How do I detect what type is "object response" and fill it into T dynamically at runtime?

Or how do I avoid doing this all together and have a better structure for my validator< T>?

Note, I can't change the base Service class and DoSomeService function signature, it is an override function from 3rd party package.

Tom
  • 15,781
  • 14
  • 69
  • 111
  • Can you use an interface, IValidator, and then make each implementation of IValidator have a Validate() method that encapsulates its own validation for that type? This would reduce the need for the unknown generic, I would think. – Dmitriy Khaykin Mar 09 '13 at 01:22

2 Answers2

2

If you truly want this to be dynamic the best way is to use reflection

void DoSomething(object response)
{
    var type = typeof(Validator<>);
    var boundType = type.MakeGenericType(response.GetType());
    var validator = Activator.CreateInstance(boundType);
}

Even with this solution though you won't be able to use Validator<T> in this context because you still don't know what T is. T must be defined statically to be used in this manner. You will need to break up Validator<T> to a generic and non-generic base type and use the non-generic type within the DoSomething method

Validator valdiator = Activator.CreateInstance(boundType);
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
1

That's not really what generics is for. Rather, you would have either a base class with virtual methods that do the validation or have a requirement that the concrete types implement a particular interface that has the validation methods on it.

  • I have simplified my question, the real code is actually sitting in an ValidationAspect interceptor in a Windsor method selector. Same question applies, no matter which method comes through the interceptor, I want to generalise it. I don't want to run if statements as I show above. – Tom Mar 09 '13 at 00:54