Click here to Skip to main content
15,886,422 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have an interface called IAuditable as follows:
C#
public interface IAuditable
{
    string AuditSummary
    {
        get;
    }
    string AuditDetails
    {
        get;
    } 
}

And two generic method in AuditTrail class as follows:
C#
public T GetActualOldValue<T>() where T : IAuditable
    {
        return FromXElement<T>(OldValue);
    }
    public T GetActualNewValue<T>() where T : IAuditable
    {
        return FromXElement<T>(NewValue);
    }

as well as i have one property to returning Audit Summary by getting a class at run time as follows:
C#
public string AuditSummary
    {
        get
        {
            if (HasNewValue || HasOldValue)
            {
                string libraryVal = GetLibraryValue();
                Assembly assembly = Assembly.Load(libraryVal);
                foreach (Type type in assembly.GetTypes())
                {
                    if (type.IsClass == true)
                    {
                        if (type.FullName.EndsWith("." + ClassName))
                        {
                            /*Here i want to call GetActualNewValue<foundClass>().AuditSummary
                             * or GetActualOldValue<foundClass>().AuditSummary;
                             */
                        }
                   }
                }
            }
            return "";
        }
    }

As you know we can find class at run time in specific library, Please note i don't want to call a generic method at run time,just wanna call generic method with founded, in other words how can i pass a specific class to GetActualNewValue<...>() as T,
C#
AuditTrail auditTrail = AuditTrail.GetAuditTrail(76);
string summmary = auditTrail.GetActualOldValue<DTClient>().AuditSummary;
string details = auditTrail.GetActualOldValue<DTClient>().AuditDetails;

This code work perfectly but the main problem is DTClient must find at run time and define as T for GetActualValue.

Thanks all.
Posted

1 solution

It's not clear where do you want to find the type to be used in the generic, from what set of types. It's even less clear if such approach is reasonable or not. By some reasons, I doubt it.

However, the problem itself is technically simple. The only problems are: 1) what happens if you find more then one class? 2) where do you want to get the instance of the class? instantiate it?

However, let's assume that you already have some set of types, you stop search if you find the first of types which satisfy the criterion, and you want to instantiate the type when you find it, it would be pretty simple. Let's also assume you have some assembly where you want to find all the types it declares and return the instance of the first suitable type found. We will also need one more assumption: the type implementing IAuditable should have some certain signature. In my example, it will be the parameterless constructor (most usual case):

C#
using System;
using System.Reflection;

//...

static IAuditable FindFirstAuditable(Assembly assembly) {
    Type[] types = assembly.GetTypes();
    string interfaceName = typeof(IAuditable).FullName;
    foreach (Type type in types) {
        Type interfaceType = type.GetInterface(interfaceName, false);
        if (interfaceType == null) continue;
        ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); // a constructor without parameters
        if (constructor == null) continue;
        return (IAuditable)constructor.Invoke(null); // the cast it safe,
                                                     // because we already tested that the interface is implemented
    } //loop
    return null;
}


If you want just the type, you can return the type instead, of you can call GetType() on the object you have.

As you can see, too many assumptions. Also, it could be slow. But this is because your goals are not clear enough. I hope it will be enough for you to understand what techniques you could use and do it in your way. And I would recommend you to seriously review your approach.

—SA
 
Share this answer
 
v2
Comments
ARIA 5 13-Aug-13 0:19am    
First of all i should thank you for your reply, but it is fluent explain,
As the code shows i can find a class in specific assembly at run time, now suppose we have a generic method with the following signature:
T MethodName<t>() where T : IAuditable
While calling the generic method we must define a class type which found at run time.
The main problem is how i can call the generic method by the found class.
Sergey Alexandrovich Kryukov 13-Aug-13 1:49am    
On second thought, you cannot use the found class to substitute it to the generic type of method, because the generic type only becomes a complete type statically. Whatever you do, you can have the complete type from a generic type the way you use it in the code you write if you actually type the instantiation of the generic, manually substituting the generic parameter. Pretty obvious, isn't it?

You can only emit the code out of generic type declaration + dynamically found type or its instance. This is done 1) using System.Reflection.Emit, 2) CodeDOM (with actual source code text generation and then building some assembly on the fly). Both approaches make me thinking: won't it defeat your purpose?

That's why I would advise you to review the whole architecture. If you want some further help, could you share your ultimate goals? Not the ones you already shared, but really ultimate...

—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900