how to achieve true loose coupling using Prism and Unity - wpf

I have developed a WPF application using Prism and Unity frameworks and I have some concerns regarding the following whether I have implemented them correctly or not.
Abstract classes / Interfaces - I have organized interfaces for all the layers in one assembly and then referenced it in the respective library for implementation. Now, the referenced library has access to all the non required interfaces of other layers. For e.g. the service layer has access to UI interfaces. Is this the proper implementation in terms of clear separation or should I split it into multiple assemblies.
View Model dependencies - I used EventAggregator mostly to communicate between view models. In some cases, I am passing the instance of other view models directly in the constructor and resolving it using DI container. I want to omit the direct view model dependency by introducing the interface to achieve clear separation. How can I organize the interface for view models into a separate assembly in such a way that the other developers could understand.To avoid creating multiple UI projects, I created only one single assembly and logically separated them into folders.
Abstract Module Class - Instead of specifying all the dependencies in bootstrapper.cs file, I factored them in respective module. Most of my class lib projects has references to Prism libraries. Thus, UI specific namespaces are added to non UI related projects. Is there any better approach to achieve this ?

Abstract classes / Interfaces
I'd go for exactly as many "interface-assemblies" as necessary, having too many of them hurts. Example: if you need to prevent layer 1 from potentially communicating with layer 3, put the layer 1-to-layer 2-interfaces in one assembly and those for layer 2-to-layer 3 in another one.
View Model dependencies
Normally, you shouldn't need to pass view models around at all. Pass around the data (a.k.a. model), the view models themselves don't hold any data that's either unavailable elsewhere or valuable to anyone but the view bound to the view model.
Abstract Module Class
Your prism application references prism... so what? As long as only the IModule implementations receive the IUnityContainer I wouldn't care at all. If someone needs to publish an event, he get's the IEventAggregator... That's an interface already, and you can inject a mock in your tests, so no need for further abstraction.

Related

PRISM modules with multiple assemblies per module

I have a WPF application that uses a layered architecture with three conventional layers: User Interface, Business Logic, and Data Layer. Now I have a requirement to split the application into vertical slices by functional areas (e.g. Customer, Product, Order). Meanwhile I would like to keep the horizontal layer separation within each vertical slice.
I am considering to use the PRISM modularity framework to accomplish this. So each functional area (vertical slice) will be represented as a PRISM module. But since my modules have a layered architecture, each module may consist of multiple assemblies.
Based on the PRISM documentation the ModuleCatalog assumes that each module is in one assembly. I am not sure how I can group multiple assemblies as one module. Any ideas if this can be done?
Edit -- I missed to mention that I want to de-couple the layers by not directly referencing the implementing assemblies for the layers. Instead I define the interfaces in an interface project for the respective layer such that only the interface project is referenced by the layer using it. Given this I still need a way to tell a module about the implementing assemblies for its layers.
You're over thinking it. Your other assemblies will just be references in your Module project. You will only add the module to the ModuleCatalog, and as long as you have your referenced assemblies in place it will work as expected.

Convert an AngularJS app to GWT (MVP)

I need to convert the following AngularJS application to a GWT application (though the question applies to any angular application). I would like to use the MVC pattern and UiBinder as suggested in the documentation but I'm unsure as to how the components of the angular application should correspond to the GWT one.
I've given it some thought already and here's my understanding - I'd be grateful if someone could say if I've got it right
Each module should become a presenter
One view per presenter
Services must be initialised in the AppController and passed to the relevant presenters (similarly to how an eventBus is implemented in the MVC description)
Now I don't know how to put multiple presenters together, though, so that they create one page. Should I create a main view that would correspond to the AppController and then pass the relevant parts of that view to each presenter?
Also, what's the best way to handle modal dialogs? Should I just include them in the view, bind to the presenter and keep them hidden initially?
I would recommend to use either Activities and Places or a fully fledged MVP framework like GWTP.
Regarding your questions:
I think that's right
One view per presenter is the usual approach. However you can also think of implementing different views for different devices (Desktop, Mobile, etc).
I would recommend to use a dependency injection framework like GIN to inject services and components into your Presenters
It depends if you use Activities and Places or GWTP. GWTP has the conecept of PresenterWidget that can be nested in Presenters. For Activities and Places you can follow Thomas Broyer's recommendation.
In general I think Presenters and their corresponding Views should be standalone components that are usually associated with a Place. GWTP has the concept of Slots (i.e. side navigation, etc) where Presenters can reveal themselves.
Communication between Presenters should be done via the EventBus.
GWTP has a concept of PopupPresenters but typically I think modal dialogs should be included in the View and handled by the parent Presenter (unless it contains a lot of business logic).
You said:
Each module should become a presenter
look at [GWT Organize Projects][1]http://www.gwtproject.org/doc/latest/DevGuideOrganizingProjects.html
It talks about modules in the section, "Modules: Units of Configuration"
Basically, a module is just for configuration. You need a module for each entry point. People often have 1 module per page.
You said:
One view per presenter
This is usually the case.
You said:
Services must be initialized in the AppController and passed to the relevant presenters (similarly to how an eventBus is implemented in the MVC description)
Like Ümit said you should use Gin
Ümit recommended GWTP I'm no expert on GWTP but I used it briefly when I was a beginner and it was hard. I don't think it's good for beginners. Admittedly, it might be worth the investment of learning it. Like I said I'm no expert on GWTP.

Splitting app's parts in their own assemblies when using Prism

The MVVM approach encourages (or just gives the possibility to) splitting a WPF or Silverlight application into Model, ViewModel and View projects so all three could exist in their own assemblies.
Using Prism (and, in my case, MEF as a Dependency Injection Container), on the other hand, one can build a modular application that is divided into a set of functional units (named modules) and each unit, in this case, is a seperate assembly.
Am I right that in this case we can separate only a Model in an its own assembly, but View and ViewModel should sit in one assembly, representing one functional module?
First of all, module is not equal assembly. You can spread a module's parts between several assemblies (including Models, Views and ViewModels). Although, usually you place classes related to a module together in one DLL or XAP file (in case of Silverlight if your module is a separated Silverlight application).
As of your case, if a Model is a shared entity which can be used by several modules, Prism encourages to place it in so called Infrastructure assembly that keeps shared non-module specific logic. Otherwise, it could be a good idea to place MVVM parts together, since they solve common business tasks. In the future, if you need to replace implementation of one of the MVVM's parts, you can do it just adding a new one and adjusting container's mapping.
Yes, Prism encourages you to put everything (models, views and view models) into one self-contained functional module.
In any case, I would strongly NOT recommend you splitting views and view models into separate projects. This is because they are tightly coupled together and are developed side-by-side.
Well, there are two recommended approaches on how you organize you MVVM application. First is when you organize your project by layers and put you views and view models into separate folders inside a project. Second, when you create folders by feature and don't separate views and view models, i.e. they lie in the same folder side-by-side. I personally choose the second one because, as I mentioned, they are developed and maintained always together and this way it is very easy to find corresponding view or view model.

NOOB Challenge Implementing MVVM in WPF

To preface, this is my first attempt at MVVM... I buy it, I'm just having a little trouble implementing it.
I'm building a utility to assist with managing a course. I have a COURSE object which contains a few properties and methods as well as a collection of MODULES. Each module has a few properties, methods and a reference to a PRESENTATION object and LAB object (each of those has a few properties. I first implemented the modele and wrote all unit tests.
My challenge is now in implemting the UI (V & VM)... specifically the view-model part of the MVVM.
The UI allows you to create a course, see the modules and then have a master-detail view into each module where you can set a few properties and such. For my view model, I created an object to encapsulate the COURSE model... exposing a few properties including an ObserveableCollection of the course modules.
I've run into a few things that are throwing me for a loop and looking for some help:
I'm not sure if I went about my VM part correctly by creating something that encapsulates the COURSE model. Because I need to access MODULES in the course as well as LABs and PRESENTATIONs in the COURSE object. Does that mean I need to create VM's for each of those as well? Seems like I'm going about this the wrong way as this approach means I'm going to encapsulate every object in the model, same goes for each method and property?
When showing the modules in the UI of the app, I need to move things up and down in the order. The methods that do this are baked into the COURSE model. The trick is when I use these methods from the view, it isn't updating the view because the courses object lives in the VM, not in the M. I can "fix" this by setting the DataContext of my listview to null and then resetting it to be the same as the hosting window (which is the COURSE), but that isn't ideal. The modules are an observable collection, but they won't update because I'm doing the work at a lower level.
Seems I'm going about my VM a bit wrong... something tells me that not everything from the model should be encapsulated within it.
You don't NEED to create VMs for Modules or Labs, having Observable collections of each is enough. But...If you need to have extra powers on each of these objects, you can have collections of ViewModels instead. (as the Josh Smith example do)
If your logic is in the model, you need to refresh the ViewModel when you do changes to the model.

Push common ViewModel functionality into a base class?

I'm using MVVM with Prism and Silverlight. I have multiple different views of one model. As I am writing more views their ViewModels seem to duplicate a lot of common code related to handling this one model. Rather than repeating the same common code in all the VMs I am tempted to push it back into the model (which would probably mix concerns too much). Or maybe into some common ViewModel base class? Or perhaps my VMs need a 2nd level of "shared VM" between them and the model? This single shared instance, 2nd-level-VM would consolidate the behavior and state shared by the multiple regular VMs.
Any comments about these issues and possible approaches?
Thanks for the comments guys. I probably should have told you more about the specific "shared" VM code in question.
I can see putting some future code in a VM base class, but the particular "shared" code I'm looking at seems to belong in an INotifyPropertyChanged implemented by the model itself. This is partly based on this other thread.
I don't think this violates SoC, because the model is inherently dynamic. Some of its properties are only valid at certain times. That dynamic nature of the model is not just something that's important for the UI, a proper unit-test would also care about it. Hence this model seems to need an INotifyPropertyChanged.
Any comments on that?
If the common code can be shared by all ViewModels, then it's worth putting it into a base ViewModel type.
If the common code is only shared by ViewModels that interact with a particular Model, then a "shared" ViewModel is the way to go.
I've used inheritance for ViewModels in the New York Times Silverlight Kit successfully to reduce replicated code. Look at the CommunityRecentComments and its parent class CommunityBase for an example.
Most "base ViewModel" classes in the variety of MVVM frameworks tend to contain the support for INotifyPropertyChanged and usually some sort of support for dispatching back to the UI thread.
Beyond that I think that if you have a number of ViewModels that share functionaltiy that should be into a base class, the more I use this pattern the more I find myself using a rather shallow hierarchy of ViewModels, a base ViewModel for code common to all view models and typically another base class under that for common functionality in that area of the UI. Usually common commands or where the UI is sharing elements.
ViewModelBase -> ProductsViewModelBase -> NewProductViewModel
In SoapBox Core, which is fully MVVM, I defined an IViewModel interface, and an AbstractViewModel base class which, as Nigel said, just implements INotifyPropertyChanged. (Note that SoapBox Core is WPF, not Silverlight, but in this case it's not a big deal. I've done some similar Silverlight work as well.)
Then I defined more interfaces (like IMenuItem) that inherit from IViewModel and more abstract classes that provide a basic implementation of those interfaces.
Now, that accounts for the whole ViewModel tree, but as you said, there's also the Model tree. I've spent almost a year working with MVVM now and here's my big epiphany: Don't write a Model. If you're building the application from the ground up, just put everything in the ViewModel, otherwise you end up duplicating a ton of code.
The only cases where I bothered having a Model was when I was using a 3rd party library that didn't implement INotifyPropertyChanged and therefore wasn't easily bound to. I believe that auto-generated code for entity frameworks might fall in here as well, but I noticed that some entity frameworks now give you the option of implementing INotifyPropertyChanged in the entities themselves.
Seriously, we should rename it the ViewModel pattern and be done with it. :)

Resources