Silverlight serialize object with cycles in object graph - silverlight

I'm having an issue serializing objects when sending them to my WCF services. My classes look like this.
public class Foo
{
public Bar Bar { get; set; }
}
public class Bar
{
public Foo Bar { get; set; }
}
This causes a cycle in my object graph. I've fixed this on the server end by using the PreserveReferencesOperationBehavior. However, I still get an error when I try to serialize the objects in Silverlight.
While I can mark my objects with [DataContract(IsReference = true)], I'd prefer not to use this method because I have a large number of classes, many of which have over 100 properties and I don't want to have to add the [DataMember] attribute to each property.
Is there any other way to tell Silverlight to preserve references?
If it matters at all, I am using EntityFramework 4 with Code First.

The infered DataContract behaviour of the serializer is present to assist in the simple DTO scenarios. If you want to do it "properly" you should be using the DataContract and DataMember attributes.
When you find you have anything other than the most simple of scenarios you just need to do things properly. The correct and only way to handle circular references is with IsReference.
Lesson here is that helpful magic pixie dust only goes so far after that you just need to put in the graft. Sorry its not the answer you were looking for.

Related

ObjectContext in ViewModel (EF + MVVM)

I'm currently writing my first MVVM application which uses EntityFramework for data access.
The Application relies heavly on the underlying database and has to add new Data to the DB in many cases.
However, I'm uncertain about whether or not it is a good idea to call the ObjectContext inside the ViewModel.
e.g.
public class SomeViewModel : ViewModelBase
{
public IEnumerable<User> AllUsers { get; private set; }
private void SomeMethod()
{
var __entities = new DatabaseEntities();
AllUsers = __entities.Users.Where(...).ToList();
}
}
I've seen solutions like this, but there are some question coming along with it.
For example how long the ObjectContext actually lives, or if one should prefer a single, global accessable ObjectContext.
Or should calls like those not be part of the VM in the first place?
Currently I can also imagine to implement like StaticHelpers for each DB table and use Methods like GetAllUsers().
In Josh Smith's sample Application about MVVM he uses a Repository thats injected in the Constructor of each VM.
public AllCustomersViewModel(CustomerRepository customerRepository)
Despite the fact that this has to be a common issue, I found no satisfying answer on how this issue is approached for smaller applications (best practice)?
In the descripton of the DbContext class on MSDN it states "Represents a combination of the Unit-Of-Work and Repository patterns", so it can act as your Repository layer, although it doesn't have to, and it is intended to be used for a "Unit of Work" which doesn't fit using a global one for the entire app. Besides keeping a single one around for everything could cause issues with cached data and other undesirable things (memory usage, etc...).
Hope this helps.

How do I assign properties of a child object based on a property from the parent using AutoFixture? [duplicate]

I'm using AutoFixture to generate data for a structure involving a parent object and complex child objects, like this:
public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public Child[] Children { get; set; }
}
public class Child
{
public string Name { get; set; }
public int ParentId { get; set; }
}
Is there a way to automatically set the property ParentId of the generated Child object to the id assigned to the parent? Right now my solution looks like this, which isn't very pretty:
var parent = fixture.Build<Parent>().Without(p => p.Children).CreateAnonymous();
parent.Children = fixture.CreateMany<Child>(10).ToArray();
foreach (var i in parent.Children)
{
i.ParentId = parent.Id;
}
It feels like there's a better way to do this that I am missing? I looked into creating a custom ISpecimenBuilder but didn't manage to solve it that way either.
AutoFixture is based on a set of rules and assumptions about the API it may be asked to work with. Consider that it's been created and compiled without any prior knowledge of the Child and Parent classes, or any other types in a given API. All it has to work with is the public API.
Think of AutoFixture as a very dim programmer who doesn't even understand your language (not even English). The more fool-proof you can make your API, the easier it will be to use AutoFixture with it.
The problem with circular references like the Parent/Child relationship described here is that it breaks encapsulation. You'll need to create at least one of the class instances initially in an invalid state. That it's difficult to make AutoFixture work with such an API should mainly be taken as a warning sign that the API might benefit from refactoring.
Additionally, the .NET Framework Design Guidelines recommends against exposing arrays as properties - particularly writable properties. Thus, with a better encapsulated design, the API might be much easier to work with, both for AutoFixture and yourself and your colleagues.
Given the API above, I don't see any way this can be made much easier to work with. Consider how to remove the circular reference and make collection properties read-only, and it will be much easier.
For the record, I haven't written an API with a circular reference for years, so it's quite possible to avoid those Parent/Child relations.

Data sharing between multiple ViewModels

Further to my question how can I bind Bing Pushpins from multiple models?
This is pretty new to me and I have been searching through the web but there seem so many different approaches to MVVM and then adding in WP7 and I have got a bit confused
I am now trying to work out the best way to share data between ViewModels or even if that is the best way to do it.
What I mean is I have, for example
My models: PeopleModel, BuildingModel
My ViewModels: PeopleViewModel, BuildingViewModel (which contain Observable collections of the model)
At the moment a Timer is used to update the lists from a Webservice. The ViewModel because it is static is able to be updated during the lifetime of the application. I am not sure this is the most sensible approach though but I need some form of background sync to fit the requirements.
The People and Building contain a location but not anything regarding what image it should display as a pushpin. So I was thinking if I had a my map view containing a MapViewModel that is linked somehow to the ViewModels but I am not sure how you would do this.
I looked at MVVMLight and it seems you can register the ViewModels at start so it would be possible to add links to the other ViewModels and not worry about the lifetimes of them?
However given that there is extra information within the Models that the Map isn't interested in I wonder if is better to have a self-contained MapViewModel that contains lists of Custom pushpins of some type (so PeoplePushpins, BuildingPushpins). If I go this route I would like to know how you update the MapViewModel from data updated in the other Models.
What I mean is the running timer in PersonViewModel detects a change in the list, so updates its own list. I the need to send notification to the Map that there is an update which then will update itself from that.
Any help/advice gratefully received.
With MVVMLight you can use messaging to send data between models:
//build class to send as message
public class AddPushPinMessage
{
public PushPin PushPin { get; set; }
}
public class ReceivingViewModel
{
public ReceivingViewModel()
{
Messenger.Default.Register<AddPushPinMessage>(this, (m) => AddPushPin(m));
}
void AddPushPin(AddPushPinMessage msg)
{
//handle message
}
}
public class SendingViewModel
{
private object SendPushPin(PushPin key)
{
Messenger.Default.Send<AddPushPinMessage>(new SetPushPinMessage() { PushPin = key });
return null;
}
}

Need access to a global generic list in all Silverlight views

I have a generic list that gets loaded when a certain view is first used. Now I need this list to be accessed from all views in my project.
I've been experimenting using a Public Property in the App class. Problem is, I cannot seem to access that property from the other classes/view code (trying App.Current).
How can I access a public property generic list defined in the App class?
This is in VB.
Thanks.
The best way I've found to do this sort of thing is to create a static class (called "Globals" or "Config" or something like that), and create a static property which contains the list you want to reference. So it might look something like this:
public static class Globals
{
public static List<Customer> AllCustomers {get; set; }
}
Or in VB.NET:
Private Shared m_AllCustomers as List(of Customer)
Public Shared Property AllCustomers As List(of Customer)
Get
Return m_AllCustomers
End Get
Set(ByVal Value as List(of Customer))
m_AllCustomers = Value
End Set
End Property
And you can then get/set that property from wherever you need it:
Globals.AllCustomers = new List<Customer>();
Or:
Globals.AllCustomers = New List(Of Customer)
Of course, globals like this aren't generally a great idea, but sometimes they're the simplest solution. It's also a good idea, in my opinion, to put them in classes rather than in VB.NET modules, as it adds a namespace to the value, rather than having them in the global namespace. That helps a little bit with modularity.
If you insist on making this a property of App.Current, you need to cast App.Current to the actual class you've created, namely:
var allCustomers = ((App)App.Current).AllCustomers;
But I generally avoid adding these sorts of properties to my App class, because it makes them harder to test and breaks the idea of Single Responsibility.

Does MVVM violate DRY?

It seems that ViewModels that I make look suspiciously like other classes and they seem to require a lot of code repetition, e.g. in a current project I have:
SmartForm: Model that represents a data form to fill in, has properties:
IdCode
Title
Description
collection of SmartFormFields
etc.
SmartFormControlView View
SmartFormControlViewModel ViewModel
IdCode
Title
Description
collection of SmartFormFields
etc.
So my ViewModel is basically the same as my Model, just with all the OnPropertyChanged features for binding with the View.
It seems as I refactor and extend this that every little change I make to my model, I have to make a mirror change to the ViewModel.
This seems to violate a basic rule of patterns Don't Repeat Yourself.
Am I implementing the MVVM pattern incorrectly or is it just an inherent characteristic of MVVM that there is always a 1-to-1 repetition going on between Model and ViewModel?
I personally don't think it violates DRY since the model and view-model (I prefer the term presenter) don't point to the same information. For instance your VM and M both have a Title property, but your VM's Title property could also include validation, whereas your model's Title property could assume validity.
While it's true that The VM may contain all of the properties of the model, there is also the possibility of having validations (e.g. Title must be non-blank), data-dependencies, bindable UI-specific properties (icons, colors, brushes, etc.) which aren't part of the view.
Essentially all UI patterns have similar "duplication" in the way you state it: namely cascading modifications. Try changing a model in MVC without changing the controller.
That being said, MVVM (or any UI pattern designed to separate UI, logic, and state) can be overly tedious for simple cases such as your example. When logic becomes little more than state-pass through, the value separating the controller/presenter/view-model decreases.
In your specific case, if there really isn't any logic, validation, or UI specific properties that your VM isn't surfacing, and your model doesn't have to be persisted, serialized, or made backwards compatible with an existing structure (or adding the logic to do so in your VM is trivial), I would strongly consider combining the M and VM to avoid creating properties whose sole purpose is to get/set the underlying model's properties.
A simple solution is to have an abstract ViewModel(VM) base class that exposes the model. You can choose this VM in scenarios where it makes sense.
i.e.
public abstract class ViewModelBase<T>
{
public T Model { get; set; }
}
If you Model has INotifyPropertyChanged implemented your view will get the event. What this does do is give your View access to every property in your Model which isn't what you want some times.
also you can utilize property initializers like this(which I personally have stored in code snippets):
public abstract class SampleViewModel
{
public int MyProperty
{
get { return Model.MyProperty; }
set
{
Model.MyProperty = value;
OnPropertyChanged("MyProperty");
}
}
}
In most circumstances you view will be the one making changes to your VM and when it does any control that is bound to that property will then be told that something happened.
Hope that helps.
That's an interesting remark... indeed, it's often necessary to modify the ViewModel to reflect the changes in the Model.
It would be nice if it could be automatic... actually I think it could be possible, by implementing ICustomTypeDescriptor in the ViewModel : GetProperties would return all the properties of the model through reflection. However I'm not sure it would make sense, because the model may not consist of properties at all : it could be methods, fields, or anything, and not everything in the model would be useful in the ViewModel.
One thing that seems to have been missed here and that your simplistic example does not expose is the fact that your Views will often aggregate data that is contained within multiple Domain Model types. In this case your ViewModels will contain references to a number of domain Models (of differing types) thus aggregating a bunch of related data that a particular View may wish to expose.
Others have provided good comments on the roles of the components of the MVC/MVVM patterns. I would like to offer a fundamental observation explaining the repetitiveness no matter which pattern you select.
Generally there will be some sort of repetition between your data layer, business layer and UI layer. After all, in general you have to show each property to the end user (UI), model it's behavior (Business layer) and persist the value (data layer).
As others have pointed out, the property might be treated a bit differently on each layer which explains the fundamental need for some duplication.
When working on systems large enough (or on small projects with the right team), I tend to model this type of information in UML, and use code generation (often coupled with partial classes) to handle the repetitive aspects. As a simple example, the Last Name property might have a requirement (in my UML model) that it limit data to 50 characters. I can generate code to enforce that limit into my UI layer (e.g. by physically limiting input), generate code into my business layer to recheck that limitation ("never trust the UI") by perhaps throwing an Exception if the data is too long, and generate my persistence layer (e.g. NVARCHAR(50) column, appropriate ORM mapping file, etc.).
2012 Update
Microsoft's Data Annotations and their support in the UI layer (e.g. ASP.Net MVC) and on the data layer (Entity Framework) goes a long way toward implementing many of the concerns I previously generated code for.
Eric Evans, in his book "Domain Driven Design" mentions that Model refactoring should not be too hard, and that a concept change should not span into too many modules, otherwise, refactoring the Model becomes prohibitive, so, if you ask me, having the Model sort of 'copied' in the ViewModel certainly difficults Model refactoring.
Eric mentions that one should give more weight to Model cohesion and isolation, than to a tidiness in the division of layers based on technical concerns (database access, POCOS, presentation). That the most important concern is that the Domain Model is a good representation of the Business Domain, hence its the most important for the Domain Model to be in a single isolated layer, and not spanned in several modules, in order for it to be easily updated (refactored).
Considering what was just said, I'd use the same Model object in the ViewModel, and if I want to reduce the level of "access" to a Model object, then I'd "pass" a reference to an Interface implemented by the Model object. For example:
// The primary Model classes
public partial class OrderItem {
public int Id { get; }
public int Quantity { get; set; }
public Product Item { get; set; }
public int Total { get; set; }
public void ApplyDiscount(Coupon coupon) {
// implementation here
}
}
public partial class Product {
public int Id { get; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
}
// The shared views of those model classes
public partial class OrderItem : IOrderItemDTO {
public IProductDTO Item {
get {
return this.product;
}
}
}
public partial class Product : IProductDTO {
}
// Separate interfaces...
// You enforce the rules about how the model can be
// used in the View-ViewModel, without having to rewrite
// all the setters and getters.
public interface IOrderItemDTO {
int Id { get; }
int Quantity { get; set; }
IProductDTO Item { get; }
int Total { get; }
}
public interface IProductDTO {
string Name { get; }
string Description { get; }
decimal Price { get; }
}
// The viewmodel...
public class OrderItemViewModel {
IOrderItemDTO Model { get; set; }
}
I only know MVC and in MVC a Model-Class which contains GUI is some error. SmartForm seems to be a Form, which means it is not a model. I don't know what you are trying to program but I give you an example for a Model:
Take a Calender. You can ask the Class what date it is today, what month, how many days each month has, ...
It has no graphical representation though. The View (CalenderViewMonth or whater you want) prints a single Month on screen. It knows a Calender and asks him what to write in the different cells.
Essentially - you might have something wrong in your modeling / understanding of MVVM (which is a modern .NET-Variant of MVC).
Edit:
I just looked up MVVM on Wikipedia. Model is just like the Model in MVC. View like the View in MVC as well - only graphical representation. the ViewModel is the Glue between a generic View and a specialized Model. Some kind of Adapter. There should be no violation of DRY.
I think that yes, vanilla MVVM does violate DRY. But I've started the PDX library which I think can solve this problem in many cases. I wrote this post which I believe addresses this question.
Basically, my goal (one of them) is to have Viewmodels that don't worry about UI Notification. The PDX project is still in its infancy but if you're reading this question you might find it useful, and I would appreciate any feedback you may have.

Resources