LaurentH
LaurentH

Reputation: 301

WPF MVVM WCF client/server architecture

I want to build a basic wpf/mvvm application which gets the data from a server with WCF and allows the client to display/manipulate (with CRUD operations) this data.

So far, I thought about something like that for the architecture :

I'm clear on the Views/ViewModel part, but I have troubles figuring out the relations between the model, WCF and the viewmodel.

My questions are :

  1. How should I handle the model generated by EF ? Get rid of it and go for a code first approach, manually doing the mapping with the database ?
  2. For the WCF data transport, should I have relational properties in my model, i.e a Product has a Customer instead of a CustomerId ?
  3. Should I have an additional layer between the WCF and the ViewModel, for storing and manipulating data or is it a best practice to directly plug the ViewModel into the WCF ?

Any other tips for this kind of architecture are welcome...

Upvotes: 5

Views: 9594

Answers (2)

Mare Infinitus
Mare Infinitus

Reputation: 8192

First of all, some general information: there is a really good tutorial on MVVM by Jason Dollinger available at Lab49

edit The video covers most of the needs when architecting a WPF application. Dependency injection and the connection to WCF are also covered (but not in depth when speaking about WCF, but with a really strong way to come up with good solutions here)

The source code he developed is also available here

In my opinion, everybody who has to do with MVVM should see it!

=> 1. How should I handle the model generated by EF ? Get rid of it and go for a code first approach, manually doing the mapping with the database ?

AutoMapper can help here. Codeplex of AutoMapper Your issue seems like a perfect fit for this!

=> 2. For the WCF data transport, should I have relational properties in my model, i.e a Product has a Customer instead of a CustomerId ?

Don't mess with the model! A productid is part of orders, and orders have a customer-id. Stick to this. In your service layer, you will probably end up with ids anyway. Since you probably do not alter products nor customers here. If you do (and my orders example does not fit then), you can transport the dynamic data, not the static.

=> 3. Should I have an additional layer between the WCF and the ViewModel, for storing and manipulating data or is it a best practice to directly plug the ViewModel into the WCF ?

In most cases, I have a service layer with gets injected into my viewmodel in the constructor. That can be assumed another layer, as it handles the WCF client part and handles the "changed" events of the server side. (row changed, new row, row deleted etc)

edit If you have to dispatch your service layer events, it is much easier to have that small, leightweight layer between WCF and ViewModel. As soon as you have to, you will probably come up with such a layer naturally.

Upvotes: 2

ken2k
ken2k

Reputation: 49013

There are different solutions for the architecture of a 3-tier WPF application, but here is one possibility:

1+2) One solution is to create "intermediate" objects that represent what your client application actually needs. For instance, if your application needs to display information about a product plus the associated customer name, you could build the following object:

public MyProduct
{
    // Properties of the product itself
    public int ProductID { get; set; }
    public string ProductName { get; set; }
    ...

    // Properties that come from the Customer entity
    public string CustomerName { get; set; }
}

You can then expose a stateless WCF service that returns your product from an ID:

[ServiceContract]
MyProduct GetProductByID(int productID);

In the server side of your application (i.e. the implementation of your service), you can return a MyProduct instance build by querying the database through EF (one context per call):

public MyProduct GetProductByID(int productID)
{
    using (DBContext ctx = new ....)
    {
        return from p in ctx.Products
            where p.ID == productID
            select new MyProduct
            {
                ProductID = p.ID,
                ProductName = p.Name,
                CustomerName = p.Customer.Name  // Inner join here
            };
    }
}

3) Adding additional layer between the WCF services and the ViewModel might be considered as over-engineering. IMHO it's OK to call WCF services directly from the ViewModel. WCF generated client proxy code has the actual role of your model (at least one part of your model).


EDIT:

why MyProduct should reference the CustomerName instead of the Customer.In my case, Customer would have many properties I'd work with. Woudn't this "mapping" be too expensive ?

You can use the actual entities. But on client side, as it's a 3-tier architecture, you have no access to the DB through the navigation properties. If there was a nested Customer property (of type Customer), the client would have access to theProduct.Customer.Products, which has no sense has you can't lazy load entities this way (no DB context on client side).

Flattened "intermediate" POCOs are much more simple IMO. There is no performance issues, the mapping is straightforward and the CPU usage for this particular operation is infinitesimal compared to the DB request time.

Upvotes: 4

Related Questions