I have a Metro app consisting of several pages, all deriving from LayoutAwarePage. I've implemented navigation to and back from them. This works like a charm. What I want to do now is to share common data between these views like for example:
access to a model, let's Name it MyModel
an instance of a controller, let's name it MyController
common business logic, let's name it MyLogic
In the past I was used to "inject" those dependencies via constructor. This is now not possible anymore (right?). How can I do this otherwise keeping in mind that I want to avoid:
singletons (because of testing)
public static properties (which is similar to singletons)
Is it ok to pass kind of a context object to the Frame.Navigate() method? Does anybody have a good advice?
P.S. I want to avoid using Frameworks like MVVM light or Cocoon.
Cheerio!
It sounds like you are looking for something very simple. If that is the case, I would just add a property to App.xaml.cs.
You set/get that property from anywhere in your application with something like (App.Current as App).MyProperty. Very brute force but it works.
I have also seen the same approach but with a master container assigned to App.xaml.cs property, then an extension method with a getContainer() method - just to reduce the number of times you have to write (App.Current as App).
Ok, I guess I found a good solution for me [1]. It's still not exactly what I was looking for, because it's using the MVVM light toolkit and its Messenger concept - but it's clean.
[1] http://forums.silverlight.net/p/200771/468507.aspx
Related
Imagine you have two views, ViewModel InfoViewModel which displays information about a person and ViewModel SearchViewModel which handles searching for a person and selecting a result.
I want InfoViewModel to be able to initiate a search process which will eventually result in SearchViewModel telling view InfoViewModel that someone has been selected. Another potential requirement would be that InfoViewModel can communicate with SearchViewModel to say that this result is unacceptable and that the user should pick someone else (this should happen without the search result screen disappearing and reappearing)
Normally this would be easy to solve by InfoViewModel giving SearchViewModel a callback that would be called whenever a result is selected. The callback could also having a return parameter specifying whether the result is good or not so that SearchViewModel can clean itself up or not. However it almost seems like Prism discourages this since, at least in prism 4.0, there was no good way to navigate with an object as a parameter (you could only pass strings as parameters). One of the workarounds I'm using is to use a service to store object parameters which can then be uniquely identified in the next view by way of a string guid. This has it's own problems, but worse it feels like Prism intentionally designed against doing this.
Another way seems to be using the IEventAggregator to broadcast an event when a person is selected. I would have to filter each event based on a unique id to make sure the event I received is for me (in case for some reason there are two search processes going on). It feels like this way is just trying to emulate a direct callback but in a roundabout way.
Does anyone know of a good solution to this? If the answer is there is no good way in Prism 4.0 to solve this, you have to be on Prism 5.0 (since it supports passing object parameters) then that's fine too. I'm just wondering what other ideas are out there
There probably isn't just one "right" answer, there are just different approaches.
You can navigate to the view passing details using the NavigationParameters class in Prism5. If you are limited to Prism4, you could place the parameters in the RegionContext and then access them in OnNavigatedTo method of the the INavigationAware interface.
With regards to "returning" results, that might depend on the layout of the application. If multiple views are allowed, registering and then using an event through the event broker is the recommended way to communicate between different components. If you have just one view and you feel the event broker is unnecessary and perhaps overkill, consider using a service paired with the SearchViewModel to store the results (not dissimilar to what you appear to be doing already). Any other ViewModel can be injected with the service, so they will be able to access any property details that the SearchViewModel has set.
If the searching is limited logically within the parent view, consider using an InteractionRequest to popup the search view.
I have a Silverlight application that consists of many pages that uses Navigation Framework. What is the ideal place to store data that should be accessed across all pages (XAMLs) and throughout
the lifetime of the application.
EDIT: Forgot to mention that I am currently doing it as a static class
Static members are generally a bad idea. You have no control over lifespan or ability to easily substitute another set of data (and don't get me started on the inability to do proper unit testing). You want to use some type of shared View Model/Data model.
If you are not going the whole PRISM route (we always use PRISM now for Silverlight and WPF), or Unity, or even just MVVM, then use simple singleton accessors on your data object.
There are lots of discussions over the best patterns for C# singletons, but you can learn a lot here http://www.yoda.arachsys.com/csharp/singleton.html
Hope this helps.
I like to create a class called Session, with a static property like this public static Session Default {get {return App.Current.Resources["Session"] as Session;}}, then create a new instance of it in app.xaml like this <classes:Session x:Name="Session"/>, now you can access it in code behind with Session.Default... and you can bind to it with Source binding and it will always be the same instance. I have expanded this pattern to a more complex and flexible pattern with base classes etc but that should suffice for your purposes. I wrote this code in this web window, it might not compile, if you need more help just let me know
I was just curious if this is a good or bad practice or what the most preferred way of doing this is.
The practice I am referring to is that as I am a newb to WPF as I'm going along I have found it handy and useful to put strings, xdocuments, and domain objects into the Application.Resources in the app.xaml when their data is to be needed across the application, and for the simplicity of the static resource binding by x:key.
Good? Bad? Why? What should I do instead? Please no links to large MVVM tutorials and such, just looking for a concise answer regarding this specific practice, if MVVM has an answer for it I'm glad to hear what it is, I just don't want to read a 6 page tutorial or blog to find out..
I implement an application view model (AVM) object. Anything that needs to get exposed to the application views globally gets implemented as a property in the application view model so that I can get to it via binding. This makes for a nice consistent access method, gets me testability, implements property-change notification, gives me a place to put application-wide commands, all the stuff that you'd expect from using a view model.
The data context for every top-level window is set to the instance of the application view model. So I don't need to mess around with the resource dictionary or remember key values at all. That may sound a little weird at first - why would two windows use the same view model? - but if you want to put the same File/Exit command on every window that the application spawns, this actually makes logical sense. In such a case, the window's data context is set to the AVM, and then it contains a panel whose data context is set to a property on the AVM that's the actual context for that window. As long as you give your window element a name, binding to objects on the AVM is trivial - {Binding ElementName=TheWindow, Path=DataContext.TheProperty} - or you could expose the AVM as a property of the child view models.
The AVM pattern is subject to the same pitfalls as any one-object-to-rule-them pattern - e.g. creating a shambling beast with 200 unrelated properties. The solution's the same: aggregate those properties into service classes.
I generally don't put anything in the resource dictionary that doesn't get created in XAML. I can think of lots of valid exceptions to this general rule, but they haven't occurred in my programs yet.
Putting things in App.xaml could be a problem when:
You start branching your application into separate assemblies as the assemblies cannot 'see' app.xaml design-time - you can only find bugs run-time.
You have a magic string for pointing at your resource which is easy to misspell - or worse yet, duplicate by accident.
It is hard later to find the places any given resource is used and whether it can be safely changed ('What was it UpdateFrequency was for...')
You want it to be configurable - the AppSettings part of the app.config file is much better for these kinds of settings.
It's essentially the same problems as using global static variables for settings.
EDIT: Things, I prefer to have in App.Xaml is:
Global Styles and DataTemplates - in other words - things used for visual presentation that is there to override 'standard' settings - so usually they have no x:Key tag but rather a TargetType="{x:Type SomeType}"
Hope this helps!
This does make sense for ones shared across the application - "don't repeat yourself". I would also recommend having a project-specific resource that merges the application resources. The controls should reference that rather than the application resources.
This makes the controls in the project more self-contained.
I'd also recommend breaking resources into logical groups and merging them rather than having "one big bucket".
I have an example with a bunch of logic in my GUI class (winforms). I am going to refactor that so that there is no logic in the gui and a separate class holds all the logic.
What is that pattern? Say I had a form class called AddAddressForm, what would you call the associated file that holds the logic? AddAddressMediator (doesn't quite fit that pattern), if I was doing WPF I would call it the ViewModel (but I am not).
Sounds something like model-view-controller without the model part.
I don't think its called anything. I've tried doing that sort of thing in the past with Windows Forms, but unfortunately it didn't really work:
For each form I had another class called something like MyFormLogic that supposedly contained all of my logic for the form, with the form itself just containing a load of methods and events for manipulating the form (things like an AddButtonClicked event, and a AllItems collection property)
It seemed like a brilliant idea at the time (Yay easy unit testing!), but what actually happened is the MyFormLogic class became just as big and messy as before, and now I had a whole lot of extra pointless code exposing the extra methods events in my actual form class. (Also creating an instance of forms was a pain)
I'd recommend that instead you work on refactoring out as much logic as possible into lots of smaller classes that do 1 thing, rather than 1 extra class which deals with all forms logic (Its difficult to explain what I mean without some examples)
By the example given , it seems that your object shares some kind of common data.
Look at the Flyweight Pattern then.
I believe it is called Model-View-Presenter pattern. although it is commonly used in asp.net, it should be applied to WinForm as well.
http://msdn.microsoft.com/en-us/magazine/cc188690.aspx
Martin Fowler splits original MVP pattern into 2 patterns , Supervising Controller and Passive View, But I still like its original name , MVP.
it depends type of logic , say you have Conditonal Logic and you create different object from it , so seprating this in a new class will be pointing to Factory Method.
2- If you have complex algorithms in your class and you seprate it another class/s , you most probably using Strategy Pattern.
lot of other combinations also possible.
It's Model-View-Controller (MVC). In your example, the Model is the Address, the View is the dialog, and the Controller just mediates events from the dialog to the Address object.
Note: you may omit the Controller for really simple situations, but don't if you ever want automated unit-tests; the separation (via interfaces) will pay off.
I believe this is called Humble View.
For more details and different takes on it, see the Humble View section of the GUI Architectures page on martinfowler.com.
What you describe is still the Model-View-ViewModel pattern, which isn't specific to WPF. The core tenet is that the ViewModel contains state and logic, and the View constantly synchronizes itself with the ViewModel. This is nice and easy with WPF bindings, but they aren't a prerequisite; any stateful UI can utilize MVVM. The Forms flavor of the pattern can get quite wordy on the view side.
Sounds like your basic separation of concerns by breaking out the view and functionality into different files. Not really sure if it really falls under any sort of pattern per say, but it does remind me of web forms a liitle bit with the views and code behinds.
So I am creating a C#/Winforms application in a model-view-controller pattern. My view-controller needs to instantiate multiple groups of objects. The object groups are elements of the model and elements of the view. So for example a textbox and the model to go behind that text box.
I'm wondering if the best way to do this is to put everything in some sort of collection and tie them together with a key?
In the WinForm MVC apps I've built, I typically don't allow the controller to instantiate anything (I try and keep the "new" keyword out of my controllers).
If I need an object I ask a service for it, and internally that service is going to fetch that object from a data source (repository or the like), or in the case of a new object it will likely utilize some kind of factory to get me a new object (with any necessary pre-filled properties already set to default values, rules run, etc.).
The way I like to think about this sort of problem is this: how would I make this work (and make it reusable) if I didn't have a GUI for a view, but instead had a command-line input for my view? The logic to create/add/delete/update the model should be somewhere in your domain, not in the controller. Then the controller just becomes the mediator between the model and the view. The view becomes an I/O mechanism that is just a prettier version of a command-line interface.
Hope that makes sense.
Have you considered using WPF instead of WinForms? It has a nicer MVC-like model and built-in databinding that is much more powerful. It would probably solve your problem and help you build with more modern technology besides.
Perhaps you should design your model to match what the view needs? Then there would be only one model for the controller to pass on to the view.