Dynamic Collection.

Posts   
 
    
Colje
User
Posts: 5
Joined: 07-Aug-2007
# Posted on: 07-Aug-2007 14:35:33   

Hi simple_smile

First I want to say that I love this product, saved us countless hours

I have a question on how to "attack" this problem, and I hope you guys can help out.

I go through information_schema to collect all tablenames that have _codes at the end and populate a combobox based on that.

From there, I am using the value selected in combobox as a tablename for the datagridview.

Now, how to work with collection and still maintain the dynamic I am after? Any suggestion.

Usually we do it like this :

CustomerCollection allCustomers = new CustomerCollection(); allCustomers.GetMulti(null);

Datagrid.Datasource = allCustomers;

I am trying to do this:

(combobox value) allCustomers = new (combobox value)+(); allCustomers .GetMulti(null);

Datagrid.Datasource = allCustomers;

Again sorry for troubling you guys if this answerd elsewhere.

PS.I am using selfservicing, C# with Sqlserver2000 and .Net 2.0.

goose avatar
goose
User
Posts: 392
Joined: 06-Aug-2007
# Posted on: 07-Aug-2007 19:01:08   

Seems to me that you have to use a little reflection to accomplish this, this article explains a little further what I mean with reflection:

http://msdn2.microsoft.com/en-us/library/k3a58006.aspx http://msdn2.microsoft.com/en-us/library/system.activator.createinstance.aspx

Even with that, there a few problems that could arise from using that approach, from instance, what if the name of the table is (for some reason or another) not the same name as the EntityCollection you’re trying to instantiate. For this, I rather use Hashtable to hold the conversions between the names.

See this thread as well: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=4637

Please let me know if this was any help.

Colje
User
Posts: 5
Joined: 07-Aug-2007
# Posted on: 13-Aug-2007 15:30:04   

Hya First of all, thanks for a quick and nice response

I went through reflection and found it uneeded since we can create an instance through the Activator.

But I still get some errors which I hope you guys can help me out with.

Code:

// Variables
        DataTable dtToReturn = new DataTable();
        string nameSpace;
try
        {
            nameSpace = "FADO.DAL.CollectionClasses.Internkode7ikoderCollection";

            Type tColl = Type.GetType(nameSpace, true);
            object objColl;
            objColl = Activator.CreateInstance(tColl);


            MethodInfo[] mInfo = objColl.GetType().GetMethods();
            MethodInfo aMethodInfo = null;

            for (int i = 0; i < mInfo.Length; i++)
            {
                if (mInfo[i].Name == "GetMultiAsDataTable")
                {
                    aMethodInfo = mInfo[i];
                    break;
                }
            }

            if (aMethodInfo != null)
            {
                object[] parms;
                parms = new object[3];
                parms[0] = (object)null;
                parms[1] = (object)0;
                parms[2] = (object)null;

                object o = (aMethodInfo.Invoke(objColl, parms));
                dtToReturn = (DataTable)o;
            }

        }
        catch (Exception ex)
        {
            throw new Exception("GetDynamicCollectionData::There was an error invoking the collection dynamically::Error:: " + ex.Message, ex);
        }

and I get this error:

Code:

Could not load type "FADO.DAL.CollectionClasses.Internkode7ikoderCollection" from assembly FADO.MAIN, Version 1....." 

FADO.DAL.CollectionClasses.Internkode7ikoderCollection DOES exist, I dobbelchecked.

Question is, am I attaking this problem wrong? Should I take a different approach to create an instance of a collection?

Any help is appreciated

/Anwar

goose avatar
goose
User
Posts: 392
Joined: 06-Aug-2007
# Posted on: 13-Aug-2007 19:07:50   

Could you triple-check the casing of your collection name? Also GetMultiAsDataTable is a member of TypedListDAO, not IEntityCollection.

First of all, write the code as if you wouldn't use Activator (normal fetch code), then try to generalize it.

Colje
User
Posts: 5
Joined: 07-Aug-2007
# Posted on: 14-Aug-2007 11:27:40   

Thanks, that was acctually a typo..thanks for pointing it out.

I found the problem, its the GetType that needs version number AND publictokenkey to be able to get the type out.

I am quoting a weblog ( http://blogs.msdn.com/haibo_luo/archive/2005/08/21/454213.aspx) where I found this helpful information:

Type.GetType(string typeName) returns null !? Type.GetType gives us the ability to get type back from a string. We pass a well-written type name string to it, and expect it return that type. Sometimes, to your surprise, it returns null. For example, Type.GetType("System.Data.SqlClient.SqlException").

If the assembly name is specified in the typeName string, Type.GetType() will search inside this assembly only; otherwise, it tries to find one in the caller assembly and then the system assembly (mscorlib.dll). Anything after ',' in the typeName string is treated as assembly name. In previous example, no assembly name was specified; neither the caller nor mscorlib had a type of SqlException, Type.GetType did indeed find nothing in its search. To make it work, we need specify System.Data.dll in typeName. In contrast, Type.GetType("System.Int32") can return type System.Int32 without mentioning mscorlib.dll.

Type.AssemblyQualifiedName is a right way to tell what kind of typeName we should provide. typeof(System.Data.SqlClient.SqlException).AssemblyQualifiedName is "System.Data.SqlClient.SqlException, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". Type.GetType with this long string will succeed in .NET 2.0.

Note that in .NET, namespace and assembly name are not necessarily related. Type "System.Data.SqlClient.SqlException" is not with System.Data.SqlClient.dll (which does not exist, by the way). The separation is one reason why Type.GetType(typeName) tries not to guess which assembly should be loaded and then searched based on the type's namespace.

Other things good to mention here:

To get back a generic type, the typeName needs be like "System.Collections.Generic.List1", where the mark is(grave accent), not '(quotation mark). Writing with the wrong mark will be likely to cause Type.GetType returning null too. If we prefer throwing exception to returning null, use the overload method Type.GetType(typeName, throwOnError) More information on this API, please go search MSDN. Yiru also has a further discussion on the type name grammar here.

You can either get the publictokenkey this way after firing up command prompt under visual studio :

sn -T SomeFancySchmancyLibrary.dll

Or look under :


C:\Windows\Assembly

Thanks again for the help Goose.

goose avatar
goose
User
Posts: 392
Joined: 06-Aug-2007
# Posted on: 14-Aug-2007 23:42:58   

I'm glad it was useful. Thanks for the extra info.