Great questions, Ben.
Q: Why did I not select "Generate Partial Files"?
A: Because it pollutes the project with class files that don't do anything.
Of course I'm speaking from my PERSONAL perspective when I say that. But I really don't like generating a ton of do-nothing files. Your project fills up with a file-per-type and you have no idea whether there is anything material going on in there. This is what gives code generation a bad name.
My rule: if you see an entity class file, that means the entity is customized; if you don't, it isn't.
It is easy to create a partial class file WHEN YOU'RE READY TO EXTEND THE CLASS WITH SUBSTANCE. In it's entirety that class is: public partial class Customer {...}
As far as I'm concerned, this feature is a legacy of our legacy product (Classic) ... which generated the custom class files automatically. There was some justification for that in as much as it was not utterly obvious how to create a custom business object class file (although if I had it to do over again, I'd have preferred providing a Class template).
Q: Why is the Customer partial class file in the Silverlight project only?
A: Ahhh .... because I could get away with it?
In principle there should be no difference between the entity class on the client and the entity class on the server. So the proper way to do things is to create the Customer partial class on the full DotNet model project (the server project) and and then link to it in the corresponding Silverlight client model project.
I cheated to make creation of the templates easier and because there was no harm in cheating. But it certainly deserves explanation.
In the Model Explorer, the Customer partial class file has logic for adding and deleting. I only add or delete on the Silverlight client. Because I don't add or delete on the server, I won't miss that functionality in the server version of the model.
Q: You mean that "Customer" on the server need not be identical to "Customer" on the client?
A: True.
I'm not recommending that per se. I think there is real benefit to maintaining a single model ... with a single definition of each entity that is identical no matter where it executes.
If the application were written entirely in full DotNet, there would be only one model dll. The reason we have two dlls is that it is not possible to create a single assembly that executes on both platforms. We try to work-around that by compiling two dlls from one body of source code. We do our best to simulate a single type (that involves some heavy lifting on our part to map the two "Customer" types).
Nonetheless, Customer is really not the same type on both client and server. And, as it happens, you can get away with having two versions of Customer that are not textually the same.
This is an opportunity ... and a risk. I prefer not to incur the risk and that's why I encourage the principled approach of having only a single definition of "Customer". But I can think of at least two good reasons for diverging from the "principled" approach.
1) Differences between Silverlight and full DotNet drive you to implement your intent differently depending upon the target platform.
2) You do not want functionality on one side (client or server) to be available on the other.
Case #1 is fairly common. You could have a single class file and distinguish two implementations of the same method using compiler directives (e.g., #if SILVERLIGHT). This gets ugly and hard to maintain. I join many others in preferring to push those differences into separate partial class files. Maybe you call them Customer.SL and Customer.DotNet.
Case #2 is more rare. You may have code that should ONLY execute in one environment or the other. Maybe you have a proprietary method that shouldn't be exposed on the client. You could make it a partial method and then have a Customer.ServerOnly partial class file that implements it.
Q: What if I had asked the OM to create the partial classes ... Will those be primarily used as "Server" logic?
A: The OM generates both Server class files and Client links ... so your custom logic appears in both models.
Again, I never do this. It is certainly convenient that the OM generates the Silverlight links to go with the full DotNet, server-side partial class files. This is not a sufficient benefit to me.
BTW, Microsoft Patterns and Practices offers a Visual Studio plug-in to help you maintain the linkage between a DotNet and Silverlight project. It's called the "Microsoft Practices Project Linker" and you can get it from a
Microsoft download page. It's part of the Prism stack but quite useful on its own and it can be downloaded independently from that page.
Q: Implementing the Add and Delete interfaces on the client enables that feature in the M.E. UI?
A: Yes
There is nothing magical about these interfaces, BTW. They aren't part of DevForce and DevForce doesn't itself take a stand on whether you can or cannot add or delete. What you see is a Model Explorer design decision. You are free to emulate it or not.
Q: Why did you create this template?
A: So you could build a Model Explorer for YOUR database
We could have offered this as sample code (and will do so, if we haven’t already).
But we thought that, if you wanted to build a model explorer for your own database, it would be far easier to use a template rather than hack the sample code.
It is no accident that it makes for a neat demo. It’s pretty compelling to be able to deliver that much functionality, from scratch, in less than four minutes. And you get to see the fundamental mechanics of a DevForce-based Silverlight application in one fell swoop.
Q: Is the template our recommendation of best practices?
A: Well, there are some good practices in it
This post is already long so I won’t go into them all. But we do show some important practices such as MVVM and encapsulation of persistence operations within a façade class (the PesistenceService). There are some dubious practices too. In a real application I wouldn’t throw everything into one Silverlight project and one Server project.
Ward