Silverlight/Web Service Serializing Interface for use Client Side
- by Steve Brouillard
I have a Silverlight solution that references a third-party web service. This web service generates XML, which is then processed into objects for use in Silverlight binding. At one point we the processing of XML to objects was done client-side, but we ran into performance issues and decided to move this processing to the proxies in the hosting web project to improve performance (which it did). This is obviously a gross over-simplification, but should work. My basic project structure looks like this.
Solution
Solution.Web - Holds the web page
that hosts Silverlight as well as
proxies that access web services and
processes as required and obviously
the references to those web
services).
Solution.Infrastructure - Holds
references to the proxy web services
in the .Web project, all genned code
from serialized objects from those
proxies and code around those objects
that need to be client-side.
Solution.Book - The particular
project that uses the objects in
question after processed down into
Infrastructure.
I've defined the following Interface and Class in the Web project. They represent the type of objects that the XML from the original third-party gets transformed into and since this is the only project in the Silverlight app that is actually server-side, that was the place to define and use them.
//Doesn't get much simpler than this.
public interface INavigable
{
string Description { get; set; }
}
//Very simple class too
public class IndexEntry : INavigable
{
public List<IndexCM> CMItems { get; set; }
public string CPTCode { get; set; }
public string DefinitionOfAbbreviations { get; set; }
public string Description { get; set; }
public string EtiologyCode { get; set; }
public bool HighScore { get; set; }
public IndexToTabularCommandArguments IndexToTabularCommandArgument { get; set; }
public bool IsExpanded { get; set; }
public string ManifestationCode { get; set; }
public string MorphologyCode { get; set; }
public List<TextItem> NonEssentialModifiersAndQualifyingText { get; set; }
public string OtherItalics { get; set; }
public IndexEntry Parent { get; set; }
public int Score { get; set; }
public string SeeAlsoReference { get; set; }
public string SeeReference { get; set; }
public List<IndexEntry> SubEntries { get; set; }
public int Words { get; set; }
}
Again; both of these items are defined in the Web project. Notice that IndexEntry implments INavigable. When the code for IndexEntry is auto-genned in the Infrastructure project, the definition of the class does not include the implmentation of INavigable. After discovering this, I thought "no problem, I'll create another partial class file reiterating the implmentation". Unfortunately (I'm guessing because it isn't being serialized), that interface isn't recognized in the Infrastructure project, so I can't simply do that. Here's where it gets really weird. The BOOK project CAN see the INavigable interface. In fact I use it in Book, though Book has no reference to the Web Service in the Web project where the thing is define, though Infrastructure does. Just as a test, I linked to the INavigable source file from indside the Infrastructure project. That allowed me to reference it in that project and compile, but causes havoc in the Book project, because now there's a conflick between the one define in Infrastructure and the one defined in the Web project's web service. This is behavior I would expect.
So, to try and sum up a bit. Web project has a web service that process data from a third-party service and has a class and interface defined in it. The class implements the interface. The Infrastructure project references the web service in the Web Project and the Book project references the Infrastructure project. The implmentation of the interface in the class does NOT serialize down, so the auto-genned code in INfrastructure does not show this relationship, breaking code further down-stream. The Book project, whihc is further down-stream CAN see the interface as defined in the Web Project, even though its only reference is through the Infrastructure project; whihc CAN'T see it.
Am I simple missing something easy here? Can I apply an attribute to either the Interface definition or to the its implmentation in the class to ensure its visibility downstream? Anything else I can do here?
I know this is a bit convoluted and anyone still with me here, thanks for your patience and any advice you might have.
Cheers,
Steve