Search code examples
c#wcftransfer

How to use a variable as type


I want to transfer BusinessObjects from one PC to another. If I think about a number of around 40 different object types to transfer the use of many contracts for the different objects would seem to be quite some overload for always the same task: "Send Object A to Computer B and save object to DB" (objects all have a persistent method).

As the Objects can have many different types, I only want to to use a generic method to:

  1. serialize a BO object
  2. transfer it to another PC
  3. deserialize it with correct type
  4. make a consistency check
  5. save to db
  6. is my problem.

At the moment I'm thinking about sending the type as eytra information. Then I want to do something like:

BinaryFormatter aFormatter = new BinaryFormatter();
aFormatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
Object.ParseTypeFromString(aObjektType) aObject = aFormatter.Deserialize(stream) as Object.ParseTypeFromString(aObjektType);

And afterwards just use generic methods from a base object to save object to database, to keep the transfer classes as simple as possible.

Is there a possibility to do something like this? Or am I going in a completly wrong direction and it would be easier to achieve this task with another approach?


Solution

  • If you don't know the type in advance, you cannot currently be doing anything in the C# that depends on the type. BinaryFormatter will already be deserializing it with the correct object type, but you code can usually just refer to the object as.... object:

    object aObject = aFormatter.Deserialize(stream);
    

    At this point, there are various options available to you:

    • use a common interface / base-class
    • use dynamic (interesting uses of dynamic include calling the most appropriate overload of a method, and switching into a generic method)
    • test the type explicitly with is, as or GetType(), for special-casing

    As an example of the middle option:

    object aObject = aFormatter.Deserialize(stream);
    GenericMagic((dynamic)aObject);
    OverloadMagic((dynamic)aObject);
    
    ...
    
    void GenericMagic<T>(T obj) // possibly some constraints here too
    {
        T x = ... // now we *have* the type, but as `T`;
                  // of course, you still can't do many exciting
                  // things unless you add constraints
    }
    
    // the correct one of these will be chosen at runtime...
    void OverloadMagic(Customer cust) {...}
    void OverloadMagic(User user) {...}
    void OverloadMagic(Order order) {...}
    

    Frankly, if I've had to deserialize (etc) something unknown I usually prefer to stay non-generic, just using object, GetType(), and maybe some reflection - it is still generic, even if it doesn't use generics.