views:

320

answers:

3

I'm using some generic classes as data containers, and am using them to pass data to and from a wcf service. Because of the way WCF mangles generic names on the client side into a class named something like "ListOfBlah231546797646", I'm adding a reference to the real assembly as a "KnownType".

Silverlight needs to consume these services, but can only reference "silverlight assemblies". I've moved the classes to their own "silverlight assembly" and can reference them from silverlight, but when the service runs I get a "cannot find referenced assembly" error on the System.Runtime.Serialization assembly.

It turns out that Silverlight has it's own set of binaries, all labelled version 2.0.5.0. These aren't in the service's GAC and therefore the exception is thrown.

Because of this I can't reference my "Silverlight Assembly" from my service's code. Is there any way I can get around this issue, making the two flavors cross compatible when they get serialized?

This question is similar, but none of the answers help. Any ideas? similar question

+1  A: 

There are two ways that I've done this in the past.

First and easiest. Add the WCF Service as a ServiceReference into Silverlight. This will take care of regenerating all the class libraries and refreshing them when needed.

Second, store two copies of the classes, one in silverlight and one in the .net 3.5 clr. Then ensure that the DataContract Names and Namespaces match. If you add the ServiceReference in silverlight then in explorer view the ServiceReference folder and look at the Reference.cs file you'll see the classes generated and can copy those.

bendewey
This actually won't work because my classes are Generics. Rather than my MyClass<T> I get something like MyClassOfType12315125.I don't think the second option will work either because of the way serialization works. I don't believe that .net will think the types are the same.
Matthew Timbs
Can you add a ServiceReference and check the output?
bendewey
What do you mean? The generated proxy class doesn't use generics and is named awfully, like the example I gave.
Matthew Timbs
A: 

Not sure if it is possible in your scenario, but have you thought about providing your objects serialized as Json to your silverlight client? Then in your silverlight app you can use the JsonObject in silverlight. That way you avoid having another set of model objects in your silverlight app.

JsonObject user = (JsonObject)JsonObject.Load(responseStream);
bool isMember = user["IsMember"];
string name = user["Name"];
int age = user["Age"];

The example is from this msdn sample

The nice thing about this approach is also that you have linq support in silverlight, and this is usable by your ajax clients as well. It is also more secure than exposing your real objects to the silverlight app running on the client.

Dan
Does JSON support Generics?
Matthew Timbs
If you serialize a List<MyObject> you will get a array of MyObject in JSON. So the serializer supports Generics lists, I am not sure how it would handle serializing MyGenericClass<MyType>.
Dan
I can get something similar with the standard soap service reference. I don't like how it creates an ugly decorated name, and also can't use any of the logic in my real, true class. I know this isn't "true" SOA, but I own both server and client and am trying to figure out a way to share code
Matthew Timbs
One other solution might be Rocky Lhotka's CLSA.Net for silverlight. You will have to adopt the framework, but it might help: http://www.lhotka.net/weblog/CategoryView,category,Silverlight.aspxWhatever solution you choose, you are going to have to do your homework! ;-)
Dan
+3  A: 

The way I share code between Silverlight and normal CLR, is to use the "add as link" feature with C# projects. So it ends up looking like this:

| SilverlightLib
|   File1.cs
|   File2.cs
| ClrLib
|   File1.cs <as link>
|   File2.cs <as link>

Then VS works fine, and both sets of code get compiled. The annoying part is where the Silverlight framework doesn't line up. (WCF has some parts that don't exist in SL.) In that case, you'll need to use the preprocessor "#if SILVERLIGHT" to make the code target both platforms.

This has worked pretty well so far. This way, I can write code, test with VSTS, but still have it work on SL from the same source. A few tips:

  • Always edit from the SL project -- this way the editor will limit to SL, and you won't get surprises later on.
  • Sometimes you have to close the opened file for Intellisense to update in the other project.
MichaelGG
This does work, however, WCF is not able to recognize the generic class, and the KnownType attribute won't work. I've found a different way of solving the problem but your answer was very clever and will work for folks who want to share code that isn't so intertwined with WCF.
Matthew Timbs