MVVM DataService and persisting data across ViewModels - windows-phone-7

I am using MVVM Light and I have ended up storing some data in the DataService. This has happened because I need a place that shares some data (a list of objects) across ViewModels (I don't want the next ViewModel to go get the data from a web service again).
Am I breaking a pattern here? It feels like I shouldn't be keeping data in the DataService and that it should only deal with the access of data and returning it to the ViewModel. But I am finding the fact that the DataService gets inserted in to each ViewModel very useful for sharing data between them.
how else could this be done?
Thanks for any help,

There are a few options:
If the data is in a local db on the phone, your best bet is to pass an Id from ViewModelA to ViewModelB. In that case I believe it's ok to read the DataService again.
If the data is a rest service, ViewModelA could call GetData(1, true);, where the method signature in the DataService is GetData(int id, refresh=false). Then ViewModelA can pass the Id to ViewModelB. When ViewModelB makes the call GetData(1), you can return the cached values from the data service. If for some reason the cached value is null, fetch it again.
I tend to follow that pattern now, I use to inject an SharedData singleton into any view model that needed to share data but it felt smelly. Like a global variable. That's probably ok for some application state things but for sharing parts of the model, it didn't feel right. ViewModelB depended on SharedData and if that didn't get set, then what.
I'd be curious to hear how others do this.

Related

Lost in a simple MVC case - how do I return multiple Users?

I'm not sure which title would be more descriptive, so I kept it this way. I feel kinda lost in the world of MVC.
FYI: I use PHP, but that doesn't seem of much importance in this particular case.
My problem is as follows:
I have a UserController containing the following methods:
login
new
show
overview
Then I have my UserModel, containing - in this case - roughly the same methods:
login
create
fetch
The problem is: what do I keep my user data in once fetched from the database (or XML feed, or webservice, or whatever...)? I thought of a User 'business object', containing all (relevant) properties from the database. Then, when fetching the users from the database, I instantiate a new User object for each user I fetch. If only 1 user returned from the search, I return only the User object. If more users get returned, I instantiate a UserCollection object containing all User objects - in which case I can iterate over them, etcetera.
Is that a correct way of dealing with users in MVC?
And then: imagine I made an overview of 10 users. 5 of them get edited at once - imagine a status modification using checkboxes. How do I process the changes? Do I loop over all changed User objects and store them back in the database? Then it would start to look like an implementation of the Active Record Pattern, something I'm told not to use.
I hope someone can clarify which classes and/or methods I'd need to solve this 'architectural' problem.
Since it is a rather lengthy discussion. I will give the link to an article that I have written on MVC, trying to explain it in simple terms. You may want to take a look at it.
What is MVC pattern about?
If I understand correctly, your UserModel is a bit off;
the Model part of MVC is intended as a programmatic representation of the real world model.
Meaning- it represents all the properties and actions of the real-world subject. The classic example is the Car class, which has properties such as Wheel, CurrentSpeed, and actions such as GoForward(), GoReverse() etc..
So, in your case, I think your model should be what you described as a 'user business object'.
Your controller would be responsible for fetching the UserModels from storage (or wherever), and updating them back.
your workflow would be something like this:
View would call the Controller's GetUsers.
Controller goes to storage, and fetches a list of UserModels.
Controller returns them to the view.
View displays them in some way.
And the other way around for updating.
The UserModel class would be responsible for logic that pertains to individual users (for example- ChangePassword()).

MVCContrib CustomPagination WCF Serialization

All the parameters for CustomPagination<T> (datasource, page number, page size, and total items count) I retrieve in the WCF Service. It would be awesome if I could instantiate CustomPagination right there, in WCF and pass it back to my application. However, it looks like it cannot serialize CustomPagination object because it misses attributes like [DataContract] and [DataMember].
I know I could pass back all of the values required for CustomPagination separately or in another custom made object, but it would be a lot nicer to pass back just one ready to use CustomPagination object. Any suggestions on this?
Error that I get when try to update my service reference in my application:
Type 'MvcContrib.Pagination.CustomPagination`1[Myproject.WCFServices.DataContracts.User]'
cannot be serialized.
The User object is marked with appropriate [DataContract] and [DataMember] attributes.
As much as I dislike all the 'what do you want to do that for'-posts around here, here goes :)
I would like to respectfully question the following:
but it would be a lot nicer to pass back just one ready to use CustomPagination object
I do see your point. But to me, the mvccontrib stuff is strictly mvc (eg front-end). I would go out of my way not to reference it from my wcf backend service. As it stands, I don't have to go out of my way as the easier solution (as you point out) is to just create the CustomPagination in the controller (which is what I do).

Updating a many-to-many relationship

I've asked the question a few different times in a few different ways and I haven't yet gotten any responses. I'm trying again because I feel like my solution is too convoluted and I must be missing something simpler to do.
Using EF 4.1, POCO, DbContext API, AutoMapper, and Razor in an MVC 3 application.
I have a many-to-many relationship between two of my entities: Proposals and CategoryTags. I can successfully map (Automapper) a Proposal to my ProposalViewModel including the collection of CategoryTags.
In my View, I use javascript to allow the user to add, update, and remove tags by dynamically creating elements, each one that stores the ID of the chosen tag.
I can successfully post my ViewModel back to my controller with it's CategoryTags collection populated (although only with the ID property for each CategoryTag).
When that ViewModel is posted back to my controller, I don't know how to get those tags from the ViewModel and add them to my Model in such a way that db.SaveChanges() updates the database properly.
The only way I've had any success is to disconnect the CategoryTags collection in mapping (by namig them differently), iterate through each tag and manually look it up in my context and then call the .add() method. This is sloppy for a number of reasons which leads me to believe I'm doing it wrong.
Can anyone offer any direction at all?
UPDATE:
For anyone who is interested, my functional code:
Dim p As New Proposal
Dim tempTag As CategoryTag
p = AutoMapper.Mapper.Map(Of ProposalViewModel, Proposal)(pvm)
db.Proposals.Attach(p)
db.Entry(p).Collection("CategoryTags").Load()
For Each ct In pvm.Tags
tempTag = db.CategoryTags.Find(ct.Id)
If tempTag Is Nothing Then
Continue For
End If
If ct.Tag = "removeMe" Then
p.CategoryTags.Remove(tempTag)
Continue For
End If
p.CategoryTags.Add(tempTag)
Next
db.Entry(p).State = EntityState.Modified
db.SaveChanges()
Return RedirectToAction("Index")
The only working way is doing this manually - you can read full description of the problem if you want. The description is related to ObjectContext API but DbContext API is just wrapper suffering same issues (actually DbContext API suffers even more issues in this scenario and because of that I will skip solution with manually setting relationships).
In short. Once you post your data back to the controller you must create new context instance and attach your Proposal and realated CategoryTags. But after that you must inform the context about changes you did. It means you must say context which tags have been added to proposal and which have been removed. Otherwise context cannot process your changes because it doesn't do any automatic merge with data in database.
The easiest way to solve this is loading current Proposal with related CategoryTags from database (= you will have attached instances) and merge incoming data into attached object graph. It means you will manually remove and add tags based on posted values.

MVC: Are Models and Entity objects separate concepts?

I asked here a while ago for some help in understanding MVC, since I'm very new to the topic. I thought I had a decent understanding of it, and this is documented in a blog post I wrote recently on the subject. My understanding basically boils down to this:
Controller: Determines what needs to be done to fulfill a request, and utilizes whatever models it needs to collect/modify as needed. It's basically a manager for a given process.
Views: Presentation only. Once a controller collects what it needs, it creates a specific type of view, hands it the information, and says "show this to the user however you do it."
Models: Behavior of the application. When the controller asks it to extract or modify something, it knows how to do it. It also knows to trigger other models to do related tasks (in my understanding, when a model tries to "vote for something" on StackOverflow, that model knows to ask if a badge should also be granted because of it. The controller doesn't need to care about that).
My question, assuming all of that is more or less accurate, is where do entity objects come in? Are models and entities the same thing, with each object knowing how to persist its own data, or are entities a separate concept that exist on their own and are used throughout the application?
My money is on the latter, since this would allow models to act independently, while all three layers (model, view and controller) could utilize the entities to pass data around as needed. Also, objects and database persistence seem like concerns that should be separated.
To be honest, the more I read about MVC the more confused I get. I'm about ready to just take the core concept (separate presentation from logic) and run with it in whatever way feels right, and not worry too much about the "MVC" label.
Yes!
My money is on the latter, since this would allow models to act independently
You don't want to bind your view to an Entity, because if the view also needs some other piece of data, you would have to it to your Entity. The model is entirely supportive of the view, and is concerned with supporting that view and nothing else.
For example, you show a list of your entities, what other data might you need? Current page number? Total number of pages? A custom message to be displayed?
This is why you should bind to a model, which you can freely add data items to as you need to.
Update
Here is an explanation of MVC in action...
The controller gets all of the data required for the request and puts it into the model. It then passes the model to the view.
The view then deals with the layout of the data in the model.
Each Model can be one entity that contains some methods to control and use its data.
Is it enough?

MVC, how view should be accessed from controller?

I'm just learning MVC so you could find my question rather strange...
My Controller have access to different shared objects through Container object passed to Controller's constructor. To access shared objects I should do $this->container->db to access Database adapter or $this->container->memcache to access Memcached adapter. I want to know should I put View object into Container with shared objects or no?
From one side it is really comfortable to take view from this container, but this way I couldn't create multiple Views instances (for example, every time I'm calling Controller's method from View I should have one more View instance). What is the solution? How should I pass View object into Controller and/or how should I create new View instances from Controller?
Thank you!
If you want that DI experience, do it on views as well, but I don't know if it really helps you anyway. Never call controller methods from views. Instead write some partial view methods and call them from views, which define the page layout (something similar to what Rails does).
IMHO if you want to get on MVC gradually, start from core principles and iteratively get to details, but don't learn architectural/design pattern as MVC by parts - architecture, design, the whole matters:)
Hmm, maybe try implementing caching for static parts. IMHO try inserting cacher object (through DI) to controller, and let that object decide if you want to send cached partial view or instantiate a new one. If you want to cache data from db, use the same pattern from controller towards models, so whenever in a controller you need models, ask db cacher object (same DI principle). Is it clear enough?

Resources