Search code examples
c#genericsserializationdynamics-gp

Generic Method, Generic Type, Generic Parameter


I'm not even sure how to describe what I'm trying to do (sorry, newb), but duplicating code because I haven't figured out how to do correctly isn't high on my list. Any help, please?

Original non-generic method:

    public static string SerializetaUpdateCreateItemRcd(IVItemMasterType o)
    {
        eConnectType eConnect = new eConnectType();

        IVItemMasterType[] myMaster = { o };

        // Populate the eConnectType object with the schema object
        eConnect.IVItemMasterType = myMaster;

        return MemoryStreamSerializer(eConnect);
    }

My attempt at generic, so close, lost at setting typed property (?):

    public static string Serialize<T>(T o) where T : eConnectType
    {
        eConnectType eConnect = new eConnectType();

        T[] myMaster = { o };

        // Populate the eConnectType object with the schema object
        eConnect.? = myMaster;

        return MemoryStreamSerializer(eConnect);
    }

Update:

Sorry, this all may just be an architecture thing, but there's around 166 possible combinations and it just seems ridiculous to code this one step for each one. I may have to do just that though...

MS Doc reference to eConnect: http://msdn.microsoft.com/en-us/library/ff623781.aspx

Example code that calls the serialization:

    IVItemMasterType o = new IVItemMasterType();

    o.eConnectProcessInfo = null;
    o.taCreateInternetAddresses_Items = null;
    o.taCreateItemVendors_Items = null;
    o.taCreateKitItemRcd_Items = null;
    o.taItemSite_Items = null;
    o.taIVCreateItemPriceListHeader = null;
    o.taIVCreateItemPriceListLine_Items = null;
    o.taRequesterTrxDisabler_Items = null;
    o.taUpdateCreateItemCurrencyRcd_Items = null;
    o.taUpdateCreateItemRcd = eConnectHelper.taUpdateCreateItemRcdFactory(eItem);

    // Serialize into string & add to list
    List<string> sList = new List<string>();             
    sList.Add(eConnectHelper.Serialize(o));

    // Submit list to eConnect
    eCreateEntity(sList);

SerializeMemoryStream code:

    public static string MemoryStreamSerializer(eConnectType e)
    {
        XmlSerializer serializer = new XmlSerializer(e.GetType());

        using (var memoryStream = new MemoryStream())
        {
            serializer.Serialize(memoryStream, e);
            memoryStream.Position = 0;

            // Use memory streamed XML document to create a string representation of the object
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.Load(memoryStream);
            memoryStream.Close();
            string sDocument = xmldoc.OuterXml;

            return sDocument;
        }
    }

Update 2:

Many thanks to both of you. After sleeping on it, I realized the error in my architecture. I have to build the eConnect object either way and I'm already building the sub-type object in the previous method call, so I've back-tracked and moved the typed serialize code into the main calling method.

I did try the reflection, and while it did compile and run, for some reason it excepted with an ObjectReference/NullReference despite, as far as I could tell, all the objects being populated.

Here's how I was using it:

    public static string Serialize<T>(T o)
    {
        eConnectType e = new eConnectType();

        T[] myMaster = { o };

        // Populate the eConnectType object with the schema object
        typeof(eConnectType).GetProperty(typeof(T).Name).SetValue(e, myMaster, null);

        return MemoryStreamSerializer(e);
    }

Solution

  • After some careful debugging this "getProperties" kept returning "null" references because the members in this eConnecType Class are "Fields" not properties... Here is the fix...

    public static string Serialize<T>(T o)
        {
            eConnectType e = new eConnectType();
            T[] myMaster = { o };
    
            // Populate the eConnectType object with the schema object 
            typeof(eConnectType).GetField(typeof(T).Name).SetValue(e, myMaster);
            return MemoryStreamSerializer(e);
        }