Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Implementing .Net generics with reflection question

Options
  • 06-02-2007 4:16pm
    #1
    Registered Users Posts: 7,468 ✭✭✭


    public class ObjectFactory<T>
    {
        public static T GetObject(DataSet ds)
        {
            // This is the first level of properties in the heirarchy
            T entity = Activator.CreateInstance<T>();
            Type type = entity.GetType();
            
            foreach (DataTable dt in ds.Tables)
            {
                // Creates an instance of T
                if (dt.TableName == type.Name)
                {
                    // This will execute for ds.Tables[0] only
                    entity = CreateObject(dt.Rows[0], dt.Columns); 
                }
                else
                {
                    PropertyInfo p = type.GetProperty(dt.TableName, BindingFlags.IgnoreCase 
                                                        | BindingFlags.Public | BindingFlags.Instance);
                    
                    if (p != null)
                    {
                        Type subType = p.GetType();
                        object obj = Activator.CreateInstance(subType);
    
                        if (IsGenericCollection(subType))
                        {
                            // Implement the collection 
                            // HERE IS THE PROBLEM
                            // The problem here is implementing the a different type for T
                            Collection<T> col = new Collection<T>();
                        }
                        else
                        {
                            // Implement an instance
                            
                        }
                    }
                }
            }
        }
    }
    

    Given the above unfinished code I have a problem, and yes I know about the reflection overhead the need to cache.

    ObjectFactory returns an instance of T using reflection to map the fields in the dataset to the properties on T. However, some of our objects have properties that are collections or other objects. When this happens the method above will, eventually, create those collections and objects too.

    I'll use collections for my question. So my problem is: Collection<T> - How do I specify a different type for T when I don't know at design time what that type is going to be?

    To put it another way:
    public static T GetObject(DataSet ds)
    {
        ...
        if (IsGenericCollection(subType))
        {
            // But I don't know what type the collection should be
            Collection<Orders> col = new Collection<Orders>(); 
    
        }
        ...
    }
    

    I'm using GetObject above to create an instance of a Customer class. This class has a generic collection property called Orders.
    To create a Customer is easy I just use ObjectFactory<Customer>.GetObject(DataSet); How do I specify the Type (Orders) for the generic collection in the GetObject method seeing as it's different from T?


Comments

  • Closed Accounts Posts: 4,943 ✭✭✭Mutant_Fruit


    // First I assume we know the type of what we want to put into this collection
    Type finalType = typeof(Orders);

    // We get the type of the generic collection with no actual "type" associated with it
    Type t = typeof(System.Collections.ObjectModel.Collection<>);

    // We then take that and make it the generic type of "finalType"
    t = t.MakeGenericType(new Type[] { finalType });

    // We get the constructor so we can create our Collection<finalType>
    ConstructorInfo info = t2.GetConstructor(Type.EmptyTypes);

    // We create our collection
    object collection = info.Invoke(null);

    Thats the best i can offer.


  • Registered Users Posts: 7,468 ✭✭✭Evil Phil


    Sadly we don't know the type we want to put in the collection but everything else is a help. Thanks, I was starting to go around in circles. I'll let you know how I get on.


  • Closed Accounts Posts: 4,943 ✭✭✭Mutant_Fruit


    Well, if you don't know the type then you cant use a generic collection. You *have* to know the type. There is no way around it! There are quite a few ways to get the type, for example Type myType = Type.FromString("System.Int"); gets me the type for "int". You might need to store that information in your dataset if it' not already there.

    When you call "IsGenericCollection(subType)" and it returns true, how does it know that subType is a generic collection?

    If you do *not* know the type of the collection you're only option is to just use a non-generic collection.


  • Registered Users Posts: 7,468 ✭✭✭Evil Phil


    Sorry, posted that early this morning and was unclear. I do know the type, I'm getting it from a PropertyInfo class in the code above and I can use use the Activator class (again in the code above) to instantiate it or use your method.

    What I meant by not knowing the type was at design time rather than run time.


  • Closed Accounts Posts: 4,943 ✭✭✭Mutant_Fruit


    in my code, replace "typeof(Order)" with p.GetType() and you're sorted.


  • Advertisement
  • Registered Users Posts: 7,468 ✭✭✭Evil Phil


    Thanks.


Advertisement