I'm building a little complex prism application. Customer requirements obliges me to utilize ModuleA features in ModuleB.
My question is whether it is breaking prism's decoupling purpose when I reference ModuleA namespace in ModuleB and navigate to its views. If yes then how can I resolve this ?
The two incarnations of the RequestNavigate method (which is the recommended way to begin navigation) intentionally specify views as URIs specifically so that the actual type of the view does not need to be specified inside module code.
Resolution of the actual types from names and of instances from the types is done by the region manager and the container respectively, both of which are configured during the application's bootstrap sequence and do not belong to any specific module.
How exactly are you currently navigating across module boundaries?
You need to use the IEventAggregator and publish/subscribe to weak events (CompositePresentationEvent<TPayload>) through it.
Here is a sample.
Here is the relevant msdn link.
Related
I am writing an app using xamarin, mvvmcross, and zxing.net.mobile. I would like to be able to use an instance of IMobileBarcodeScanner in the portable class library to do the scanning.
The issue I'm running into is that the droid version of IMobileBarcodeScanner requires a context to be passed into the constructor. I'm guessing we'd need to register the type in the view constructor so we can pass the correct context.
Since there will be multiple views, would I be able to register a different instance of IMobileBarcodeScanner for each view? Or, could I make the IMobileBarcodeScanner a public property on the view model and set it from the view constructor instead?
Thanks for your help!
There are two main ways I've worked with barcode scanners in the past.
I've launched them as 'new pages' - including using external activities and StartActivityForResult in Android
I've treated them as 'normal controls' - a bit like TextEdit fields within the current page.
When doing the first of these, I generally used a pattern similar to the PictureChooser plugin - on Android, this accesses the current context using IoC in MvxAndroidTask
When doing the second, I treat this purely as a View concern - all the ViewModel needs to provide is an ICommand and/or a string property which can be bound to the scanned event or to the scanned text.
In MvvmCross v3 I use ShowViewModel to navigate to different pages. Before converting over to Mvx I'd use the NavigationService.GoBack() method to go back to the previous page. The advantage being that the page isn't re-created.
Since the GoBack method is platform specific to WP, WInRT, Silverlight, what is the best way to handle returning to the previous page so the view model remains platform independent?
One solution might be to use ShowViewModel passing some data that the view can see and then in the case of WP/WinRT, calling RemoveBackEntry from the view. But with Mvx, there's probably a better way.
In MvvmCross v3, we provided a specific mechanism to allow ViewModels to send messages to the UI that they would like to change the current presentation.
This mechanism is ChangePresentation(MvxPresentationHint hint) and it provides routing of messages - presentation hints - from ViewModels to the Presenter.
How the Presenter handles these messages is platform and application specific.
This message mechanism is very general and it might be used for all sort of things in the future - e.g. devs might supply hints which do things like change the UI layout, which highlight part of the UI, which force the user focus on to a certain control, which cause the SIP to be displayed or hidden, etc.
For the case of closing a view model, we have provided a specialisation of MvxPresentationHint - MvxClosePresentationHint - and a helper method in a base class of MvxViewModel:
protected bool Close(IMvxViewModel viewModel)
{
return ChangePresentation(new MvxClosePresentationHint(viewModel));
}
To use this a ViewModel can just call Close(this)
When this is called, the Presenter within your UI will receive a message on the ChangePresentation method:
public interface IMvxViewPresenter
{
void Show(MvxViewModelRequest request);
void ChangePresentation(MvxPresentationHint hint);
}
For the general/typical case - where the ViewModel that is being closed is attached to the view which is the topmost Activity/Page/UIViewController, the default presenters within MvvmCross will be able to handle this message and will be able to GoBack in Windows, to Finish in Android, and to PopViewController in iOS.
However, if your UI is more complicated than that - e.g. if the ViewModel you want to Close actually corresponds to a Tab, to a Flyout, to a SplitView pane, etc, or if the ViewModel corresponds to something other than the current topmost view in the hierarchy - then you will need to provide a custom presenter implementation - and that implementation will have to do platform and application specific logic to handle the Close.
The above hint is what I recommend you use...
However, as an alternative:
If you were to feel this ChangePresentation(MvxPresentationHint hint) mechanism was simply too heavyweight/overkill for your app, then you can also, of course, drop down to a custom or Message based mechanism instead.
One sample that does this is the CustomerManagement sample - it provides a custom IViewModelCloser implementation on each platform - see:
custom interface - https://github.com/slodge/MvvmCross/blob/v3/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement/Interfaces/IViewModelCloser.cs
BaseViewModel - https://github.com/slodge/MvvmCross/blob/v3/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement/ViewModels/BaseViewModel.cs
Droid - https://github.com/slodge/MvvmCross/blob/v3/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement.Droid/SimpleDroidViewModelCloser.cs
WP - https://github.com/slodge/MvvmCross/blob/v3/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement.WindowsPhone/ViewModelCloser.cs
Touch - https://github.com/slodge/MvvmCross/blob/v3/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement.Touch/CustomerManagementPresenter.cs
I'm not completely sure about mvvmcross, but in MVVM Light what is usually done is to create an INavigationService interface that exposes these methods.
Then, each platform implements this Interface in the platform-specific way (in WP for example by getting a reference to the current frame and its content). This platform specific instance can then do all the correct actions to make sure the navigation pattern is correctly implemented.
Your ViewModels can then get a reference to an instance of the INavigationService through a Dependency Container. That way your VM is independent on the platform specifics of navigation.
I also wrote a blog post on how to use Interfaces to expose a common API for platform specific features: http://www.kenneth-truyers.net/2013/02/24/patterns-for-sharing-code-in-windows-phone-and-windows-8-applications/
The example in the blog post is about Isolated Storage, but the same principles apply to Navigation (or any feature that has different implementations on various platforms for that matter)
I have a modular application, it behaves quite like a plugin system. Module B is dependent on Module A. When B is present, then some dialogs (titles etc.) need to be altered in Module A. Also, a different entity should be used for a list when Module B is present, which I want to include in Module B, so A doesn't know about it during compile time. Creating an abstract base in A for the entity is something I want to avoid as well.
How would you implement this requirement? The modules can communicate in various ways:
1.) Microsoft Unity is used for Object creation and dependency injection
2.) The modules can communicate via a Message-System.
3.) There's an EventAggregator which all the modules can use
I don't want to sublcass the dialog in Module B and just alter the typemapping in unity, because then I'd have to provide the whole dialog in another module. Also, if some other module wants to make other changes to the dialog, it'd be impossible.
Suggestions welcome!
Without knowing specific details, I would use interfaces to blend the plug-in components/modules. Require that each plug-in component implement an interface -- say IPluginComponent or whatever makes sense. (Actually, only components that must communicate or interact would actually be required to implement the interface.) Once all modules are loaded, the host application can fire methods or events on the components.
Personally, I like to keep things data-driven and simple as much as possible; so I might favor a "two-phase" pass through the modules. This keeps the dependencies between modules simple. So in the first phase, when all components are loaded, the host application fires the "ContributeSharedData(Context ctx)" method, where each component sets any values in a shared context. (This might also be called "Init(ctx)".) The context might be as simple as a name-value-pair collection, e.g. Module B says *coll["ModuleB_Installed"] = true*, or it could add itself to a list of modules, or... the possibilities are endless. The context can be whatever class or structure is required to enable these components to work together.
The next pass -- if required -- would be for the components/modules to configure themselves based on the shared context. So the host might run through all the modules supporting the shared interface and fire the "Configure" method or event. Then ModuleA for instance can look in the context and see that ModuleB is installed, and configure its interface accordingly.
If an interface doesn't make sense for your situation, you can use any method of contributing shared data in a generic way to a common location, e.g. messaging or other common classes.
Hope this helps!
I am in the completion stage of a large project that has several large components: image acquisition, image processing, data storage, factory I/O (automation project) and several others.
Each of these components is reasonably independent, but for the project to run as a whole I need at least one instance of each component. Each component also has a ViewModel and View (WPF) for monitoring status and changing things.
My question is the safest, most efficient, and most maintainable method of instantiating all of these objects, subscribing one class to an Event in another, and having a common ViewModel and View for all of this.
Would it best if I have a class called God that has a private instance of all of these objects? I've done this in the past and regretted it.
Or would it be better if God relied on Singleton instances of these objects to get the ball rolling.
Alternatively, should Program.cs (or wherever Main(...) is) instantiate all of these components, and pass them to God as parameters and then let Him (snicker) and His ViewModel deal with the particulars of running this projects.
Any other suggestions I would love to hear.
Thank you!
Take a look at some dependency injection frameworks such as Unity (which CAL uses), Castle Windsor or Spring.NET.
These concerns are taken care of quite nicely using Microsoft's "Composite Application Library" (aka Prism) a framework for developing composite WPF applications:
http://msdn.microsoft.com/en-us/library/ff647752.aspx
http://msdn.microsoft.com/en-us/library/ff648611.aspx
Composing your views: Prism has a concept of an application shell window and a region manager. The shell acts as a bare-bones layout page where you define named place-holder regions e.g. "MainMenu" and "TabInterface". You wrap references up to your views and viewmodels in module classes e.g. "MainMenuModule" and "TabInterfaceModule", and define which region the module should be associated with. Prism will create your views and inject them into the shell regions when the application starts. This allows you to compose your views independently of each other.
Communication between viewmodels: Prism supports a mediator pattern called the "Event Aggregator". Basically you can publish and subscribe to messages via the event agregator from your viewmodels. This allows viewmodels to loosely communicate via messages, rather than having to know about each other and hooking events.
Prism advocates and supports patterns for developing components independently of each other in a loosely coupled fashion, without introducing God objects and over coupling. A big part of Prism is also it's use of IOC and dependency injection, so unit testing becomes much easier too.
I found the following article a good practical introduction to using Prism and MVVM:
http://www.developmentalmadness.com/archive/2009/10/03/mvvm-with-prism-101-ndash-part-1-the-bootstrapper.aspx
My prefered way of getting ViewModels is using a ViewModelLocater. Basically it's the God object like you imply, but it's only responsibility is to create each ViewModel and keep a reference to it. I usually add the VML to the App's resources and each view is responsible for setting it's DataContext to the correct ViewModel. If you are subscribing multiple events you can either have your VML wire them up manually, or it can create the VM that throws the events first and pass it to the dependent VM in it's constructor.
You might use Controllers (ApplicationController, Use-Case Controllers) instead of a ‘God’ class. The controllers are responsible to create the ViewModel objects and they mediate between them.
How this works is shown by the WPF Application Framework (WAF) project.
I hope I have understood your question well. I think using a God ViewModel its not a good idea. its better to have a single viewmodel for each of your views and instantiate all the related viewmodels in that viewmodel. then you can use a mediator to send message between viewmodels of that view and other views, safly. also i propuse to use wpf commands instead of events. you can find a greate article about mediator in here.
I've started playing with Ninject and from a screencast it states the following is how you set up a binding:
class MyModule : StandardModule {
public override void Load() {
Bind<IInterface>().To<ConcreteType>();
// More bindings here...
}
}
This is all very good.
However suppose you have one hundred objects used in an application. That would mean this would have one hundred bindings. Is this correct?
Secondly, I presume that given such an application it may be split into subsystems such as GUI, Database, Services and so on.
Would you then create a custom module for each subsystem which in turn would be:
GUIModule
DatabaseModule
ServiceModule
...
For each module you'd have the correct bindings that they required. Am I on the right page here?
Finally would this binding all occur in Main or the entry point for your application?
However suppose you have one hundred
objects used in an application. That
would mean this would have one hundred
bindings. Is this correct?
One hundred registered components, yes, but not necessarily registered one by one. There's a Convention extension for Ninject that allows you to scan assemblies and register types based on some defined rules. See this test as an example.
Would you then create a custom module
for each subsystem
Again, not necessarily. You might just want to register all your repositories (just to name something) in a single convention registration.
For each module you'd have the correct
bindings that they required.
As with any "module" (be it assembly, class, application) the concepts of coupling and cohesion apply here as well. It's best practice to keep coupling low (don't depend too much on other modules) and cohesion high (all components within a module must serve towards a common goal)
Finally would this binding all occur
in Main or the entry point for your
application?
Yes, see this related question.