How to share Model objects between two MVVM WPF applications - wpf

What I'm trying to do is to get two WPF UIs running on two separate computers to share state. I'm thinking to have a service running on one of the two computers hold the MVVM model objects and the two UIs can then be clients of this service, databinding to objects that live in the service. I want to be able to propagate property changes from one UI to the other. So for example, if I have a property bound to a textbox in UIOne and the same property on the same object bound to a label on UITwo, then when I type into UIOne's textbox, the text in UITwo's label updates.
I looked into using WCF for the service, but that looks like it won't work because WCF doesn't allow clients to access object references across service boundaries. And the simplest way I can imagine propagating INotifyPropertyChanged between UIs is by sharing the object by reference. So then I looked at .NET Remoting and it looks like it will allow you to share a .NET object between AppDomains.
But now I'm confused because I thought WCF replaces Remoting.
Am I misunderstanding how Remoting shares objects by reference? Would databinding to a .NET remoting object work the way I'm planning?
Does WCF really replace Remoting? Is there a way to use WCF to share an object between clients? I don't want to start using a "legacy" technology if the new one will work for me.
Is there a third option I should be considering?

Related

WPF project - Entity Framework Injection vs Application Property

I am very new to WPF.
I am trying to figure out pros/cons of various architecture patterns in WPF, while creating an application designed to interact with a database.
The application begins with a master window, which contains various buttons which load other windows which each perform CRUD operations on different tables within that DB.
I am wondering about the merits and disadvantages of 3 possible approaches:
1) Instantiate a new entity instance within the constructor for each window
2) Each window have a have a constructor which supports dependency injection of the entity object. Every time the master window instantiates a new window object, it injects its own instance of the entity.
3) As per WPF Data Binding Walkthrough Create public ObjectResult properties on a class which inherits from application, and link to this/these properties in the
<Window.Resources><CollectionViewSource>
Tag of the various windows.
Thanks
Dependency Injection is the best option giving you most flexibility...
However, you shouldn't inject something as specific as the entity object but some service provider instead which would be a specific implementation of a service Interface and would not use the entity object directly but a Model instead which would abstract away the data access specifics giving you loose coupling benefits...

Is there any reason to make POCOs into Model objects?

If I am generating POCO objects from EntityFramework, and using these to go to/from the WCF server, is there any reason to create client-side Models for the Views & ViewModels to use instead of just using the POCOs directly?
Almost all the MVVM examples I have looked at bind straight to the object returned from the WCF service. Is this good practice? Are there arguments that can be made for actually mapping the POCO to a Model and having the Views/ViewModels working with the Model object instead of the POCO?
The main reason I could think of is validation, however since the EF POCOs are partial classes, they can be expanded on to include validation.
EDIT
Most answers so far have brought up INotifyPropertyChanged as the main reason to build a separate Model. Does your answer change if you are using Self-Tracking entities instead of POCOs which already includes INotifyPropertyChanged? STEs are also partial classes which can be expanded upon to include validation.
Validation is the main reason not to bind directly to a POCO. In addition, if the POCO doesn't already implement INotifyPropertyChanged and other required interfaces, the experience working with the object on the WPF side may be less desirable, and implementing a ViewModel to wrap this makes sense.
Providing a ViewModel to wrap your POCO allows you to encapsulate the logic into ICommand implementations as well as implement required interfaces cleanly.
I disagree only slightly with Reed (an unusual circumstance to be sure). I would NOT implement a ViewModel to wrap the POCO. I would implement a Model class to wrap the POCO and expose the Models to the ViewModel via a Service layer.
The ViewModel's primary job is to appropriately present Model data to the View and react to its requests. The architecture I'm working on for this looks like so:
1 ViewModel for each View
The ViewModel calls a Data Service layer object to retrieve Model instances (not to be confused with a WCF service)
The Data Service layer issues the appropriate CRUD requests to the backend (this uses WCF, RIA, or RESTful Services for Silverlight but could be ADO.NET or EF directly for WPF).
The Data Service uses the returned POCOs to create Model objects.
Model objects wrap the POCO object and implement INotifyPropertyChanged. Model objects enforce business rules.
I'm still working through the details but I will be publishing something more concrete in the near future.
My Models accept a WCF object which exposes those properties which I wish to use in my ViewModel. I can then also extend the object as needed. My properties point to the WCF object's property and when I have to send the object back to the WCF service, I don't have to do any more work. The models inherit INotifyPropertyChanged and INotifyDataErrorInfo which the DTOs (mentioned here as POCOs) will not have. Your business logic / validaton exists in your Silverlight application and not in your WCF Service.
The View binds to the ViewModel which has a Model (or an observable collection of Models). The Models have a WFCObject which is a DTO (mentioned here as POCO). I use my ViewModel to communicate with the service, MVVM Light has the models communicate with the service / provider - which I don't like.
Bind to EF POCOs if you want to do simple CRUD or you want to make something fast.
Otherwise, your server-side models will tend to be very closely related to the database, which changes very slowly, as compared to user interface. For less trivial UI, you'll find yourself putting more and more kludges just to fit your database model into UI (or otherwise, which is even worse).
Also, there are performance issues (e.g. would you like to transmit whole entity when for UI you need only couple of properties?), and maintenance issues (e.g. if you would like to validate premium customer's order quite differently from ordinary one).
See also http://ayende.com/Blog/archive/2010/08/06/data-access-is-contextual-a-generic-approach-will-fail.aspx
Rachel's POCO's are just dumb objects generated by EF and used for transport (DTO). Therefore, they shouldn't have other things cluttering up their domain. This is a very nice way of designing your code because it decouples any client-side requirements from those on the server-side. That's why MVVM exists - to extend the MVC model incorporating those concerns.
There is no reason you can't bind to them in your views as long as you are not modifying them directly. You can add functionality to them by adding a partial class but I wouldn't even do that. In that case you should follow the MVVM design tenants and separate those into model objects that serve your needs in the client. This will be quite automated once you hook up INotifyPropertyChanged events to notify your views.

Please Confirm My Understanding of WCF/WPF Structure

I'm studying WCF and WPF. I've learned a lot by doing sample projects, but I'm having trouble putting everything together. It would help if I could paraphrase my understanding of proper WCF/WPF structure and invite others to confirm or correct my ideas. Here is a very broad description of how I expect my next project to work:
My persistent data will be stored in a SQL Server database. I will create a WCF Service Library which serves as an interface to the database, solving security issues and recasting the relational data into an object-oriented entity model. My application will read data through the WCF service into a memory structure which might be customized somewhat for the needs of my application, but will basically consist of one ObservableCollection for each of the entities in my data model. Because the data will be stored in ObservableCollections, I will be able to use event procedures to respond to data changes that trigger business processes. Simple user interface elements will bind directly to the collections. More sophisticated user interface elements, like a TreeView, will require another layer, called a PresentationModel or ViewModel. In the case of a TreeView, the TreeView will bind directly to the PresentationModel, and the PresentationModel will bind directly to the collections.
Have I described everything correctly?
-TC
There is nothing technically wrong in what you wrote.
Things that feel off:
... solving security issues...
Scares me because it implies, to me at least, that you will have no security issues. I would have phrased it as
provideds a centralised system for authentication and authorisation to the data from all interfaces
I would definately make use of the MVVM pattern, allow a ViewModel to expose your collections and properties that your UI binds too, you seem to have a grasp of that pattern from what you have described.
Is WCF really required for your data layer? Have you looked into Entity Framework at all?
Simple user interface elements will bind directly to the collections.
I'd advise slightly against the above. A decent model to follow is the MVVM (Model-View-ViewModel) pattern. It sounds like you've read a bit about this considering your ListViews are going to be contained in a ViewModel. I would also have your raw data models exposed to a ViewModel, and have your View bind to that. So, for your raw data models, use them like you intend to do with ListViews.
Other than that, sounds like you're spot on.

Silverlight 4 WCF RIA Services and MVVM is not as simple

[Disclaimer: I'm ASP.NET MVC Developer]
Hi,
I'm looking for some best practices with implementing MVVM pattern with WCF RIA in Silverlight 4.
I'm not looking to use MEF of IoC for locating my ViewModels. What I would like to know is how to apply MVVM pattern with Silverlight 4 and WCF RIA.
I don't want to use other stuff like Prism or MVVM Light toolkit. I found many examples on Internet showing how it is wonderful to drag and drop a datasource on the view and the job is done (it reminds me about my first VB6 developments).
I tried to implement MVVM with WCF RIA and it's not strightforward at all. If I understand, the MVVM should contain all the logic in order to unit test it in isolation but when it comes to combine it with WCF RIA it's another story. I have the following questions.
Can I use a generated metadata as model ? It would be easier to use it that if I write all from the scratch.
As I saw the only way I could get data is through DomainContext or through direct binding in the view (local ressource). I don't want the direct binding in the view, not testable at all. On the other hand I can't use DomainContext, it doesn't expose any single entity !!! All I have is the EntitySet that I can bind to datagrid. How do I bind a single Entity to the DataForm from the ViewModel ?
How do I udpate the model to the database ?
How do I navigate from one Entity to a collection of it's items. For example if I have a Company Entity I would like to show a DataForm to update an entity informations and a datagrid to show companies adresses. When saving a form, I would like to save an information to Company and an information to adress about which adress was selected as active.
Please help me understand how to do it well. Or maybe I should drop the WCF RIA and to do it with WCF from scratch ?
What do you think ?
You might be interested in this session. It explains how to use the MVVM pattern with RIA WCF Services.
I found this post useful:
http://www.astaticstate.com/2010/04/silverlight-4-using-mvvm-patter-ria.html
Some random answers...
I don't think that MEF is particuarly well suited for Silverlight. It's primarily for desktop apps, and could be adapted for other uses where the plug-ins are in the local file system relative to the app.
MVVM requires that you understand roles. The "view" is your XAML and code-behind. The code-behind should handle events from the user control, but very little more than that.
The ViewModel holds the data that the user control will bind to. Generally, the ViewModel is bound to the View as its DataContext, so that everything in the form can databind to properties in the ViewModel. The ViewModel must implement INotifyPropertyChanged, and raise property changed events for every property that the form databinds to.
You'll probably want to create an ObservableCollection, using an EntitySet as your source. This will handle INotifyCollectionChanged for databinding purposes. If the entities in the EntitySet also handle INotifyPropertyChanged, then you're in good shape on databinding for collections.
You can create a property for an individual entity, and databind to that, assuming that change notification is also implemented (both for entity members, and for the entity property).
RIA Services will regenerate the DomainContext on each build, which helps a little in keeping it in sync. It's intended to be a service layer above an ORM, though, so your ORM or other data mapping will still have to be maintained by other means.
I haven't looked at the final release of RIA Services, but I wasn't hugely impressed with the beta version. I'd rather have good entity classes defined on the server, and share them with the Silverlight project. It's not easy to set up, though, and requires some non-trivial WCF that doesn't rely on service referernces. (RIA Services final release may have cleaned some of this up, but the native WCF service reference in Silverlight is pretty much evil, mainly because it doesn't automatically recreate generated classes, and it hard-codes the URI for the server-side service.)
Metadata was another problem with RIA Services beta. It's easier to attach metadata attributes directly to your DataContract class and the individual DataMember properties, if you control the entity source. Again, that may mean not using RIA Services. Writing a separate metadata class, as was required for the RIA beta, wasn't a good solution.
I ended up not using RIA Services for Silverlight 3, and didn't regret it. Here's an excellent article on WCF and Silverlight. Although it says Silverlight 2, it's still on-target for any Silverlight release.
I do recommend MVVM Light. Source is available on Codeplex, if that's an issue. It provides messaging and commanding support, as well as a ViewModelLocator; while the latter takes a bit of work to understand, it's really a good extension to the basic MVVM model.
Hope this helps.....
Just thought I would let you know about a project I am working on - just got our first release done. Provides a great simple way to approach MVVM for Silverlight + RIA Services specifically. Simplifies a lot of the MVVM stuff, and provides some more controller-like functions with the Notifications class. http://slmvvms.codeplex.com/

Silverlight design pattern for performance - very rich client UI

Following on from this initial investigations on Silverlight architectures, I have some new requirements to consider.
We expect our Silverlight client UI to be graphically heavy, with a GIS interface, multiple charts, gauges and datagrids arranged in a Widget style fashion. New widgets will be dynamically generated by the user.
Suppose a user wanted to dynamically create a chart widget from an existing datagrid widget pre-populated with data. It appears to me that if we were using a MVVM pattern with the view model on the server, this would result in an unnecessary call back home when the required data is already located in the client.
Now obviously the server needs to know about this new chart widget on the client, but how do I create the widget in the client first (with the existing client side data) and then notify the server about the new changes?
In our intranet, the network link between the client and the server is not particularly good so performance is critical.
It seems from my initial research that the common Silverlight architecture patterns call for as much of the business logic to be pushed back to the server. I understand the reasoning for this, but fear that it will really hurt the usability of our application.
Are there particular design patterns that address this issue? Is this 'client-binding' supported within MVVM, Prism or other common Silverlight architectures?
Is there a more formal name for what I am attempting to describe?
I am quite new to both Silverlight and design patterns such as MVVM, so please correct me if any of my assumptions are wrong.
The MVVM pattern is for separation of concerns. It does not define how or where you get your data.
The model, is data. It can be data you get from any arbitrary source. In silverlight, the most common way to get data is via a webservice (SOAP/REST). But your model can be any data from anywhere.
The view model is just another class that probably implements the INotifyPropertyChanged interface (So you bindings can automatically be updated). This class is an abstraction for your view's data. Let's pretend it has a string property called "FirstName".
The view is your UI (A user control in SL). You setup your bindings here to your ViewModel. IE, .
The view and view model are put together when you set your views DataContext. myView.DataContext = new MyViewModel(); There are many ways to set the DataContext depending how you want to set things up.
Prism is just a framework to help write decoupled applications in WPF/SL. It does not enforce the usage of any UI pattern (ie, MVP/MVC/MVVM). What it does come with is a bunch of classes can be used to assist with MVVM development, such as a mediator (EventAgggregator) and a dependency injection container (Unity).
So enough digressing...What I would suggest, is you have a web service where you can get all your data. You SL app would get that data (most likey the web services will be called in the view model). That data now exists on the client side and you can setup your VM to bind to this data in your view.

Resources