I'm developing a project using the MVVM pattern in WPF.
One of the key benefits to MVVM is maintaining clear separation between business logic and presentation.
As a test to see how well separated everything actually was, over the weekend I spiked moving all ViewModels, Models, and business logic to a separate .dll. The .exe was left as a thin presentation layer.
This worked, seamlessly, first try.
I've already seen benefits to keeping views (xaml, presentation) in the .exe and core logic in its own dll. For example, there's no longer any dilemma in my mind about whether code-behind in Xaml is an issue: I'm comfortable with it if it becomes necessary, since I know it's presentation specific.
So far this exe/dll separation has worked so well that my question is: Has anyone experienced any downside to this approach?
Related question: Implementing MVVM in WPF without using System.Windows.Input.ICommand
We use this kind of separation in all of our products because it helps us to see if any code violates against the UI - business logic separation.
Most times we do it the same way as you have suggested:
Sample.Presentation.exe (Contains all the WPF stuff, thin assembly)
Sample.Applications.dll (Is responsible to the application's workflow, here are all ViewModels)
Sample.Domain.dll (Here are the business rules)
We don't have encountered any issues yet and I don't expect to see any problems in future.
I don't see any spcific issues with this approach besides the general pro/con for using few/many projects.
2 weeks now with my Model & View Models in a dll, my xaml in an exe and no problems whatsoever.
The actual question is ... what are assembles for?
They are a way to separate logic making it unavailable to other code unless you add a reference, so in fact they are a way of hiding parts of code from other parts.
Given this purpose and the way you are using it I would say that you're doing it right.
Having said that I find much easier to verify that the Views do not have any code behind in code reviews and keep the views in the same assembly. Less projects = faster compile and load times.
Related
Is there a way, given a database or some other source specification for an application, for an entire WPF or Silverlight / XAML application to be generated that emits best practices?
For example, assuming I have a well-normalized database (or some other kind of base specification for an app), is there a tool that can create a well-formed MVVM application. This would include...
XAML (Views) for all of the tables (list and edit) with no code-behind
ViewModels that emits properties extracted from the db schema along with commands or behaviors for all of your standard CRUD operations
Models built with the repository pattern (or some other db abstraction) with interfaces that emit the table design and relationships and a default implementation of your choice (sql, sql ce...whatever).
An ideal tool like this would only do a "first pass" of the application after which the developer would make all necessary changes and modifications.
I don't think there is any such tool but it seems like a tool like this should be possible.
Another related question, in the absence of such a tool (or even if there is one), what tool(s) are best used to get me from a database design (or some other kind of base specification for an app) to working app.
What STEP-BY-STEP process do you take to get from design to basic working application in a couple of hours?
I am just trying to figure all of these practices and patterns and I am getting a pretty good grasp of the pieces but not sure what workflow to use to make it all work together quickly but still allows unit testing of separate concerns.
Thanks in advance.
Seth
Not sure if this is what you are looking for, but you can use LightSwitch
From a process perspective, I build and test my ViewModels first. That allows a division of labor between designing and wiring up the UI and pulling data into the ViewModel.
Is it possible to share viewmodels across platforms - WPF/Silverlight? I started down the path of putting my VMs in a separate assembly and soon came to ICommand - which then led me to ask this question? Is this possible, and if so is it good to do so? We have a possibility in the future of having a client application for WPF and Silverlight, so I would like to not have to duplicate VMs for both.
You can potentially do this using the Portable Library Tools CTP. This allows you to target the full framework as well as Silverlight in a single library project.
Otherwise, it is possible, sort of. You still need two separate projects (for practical purposes), but can typically use a single source file. Have each project using the same source files keeps the reuse in place - but does require manual synchronization of the files. You can also add platform-specific functionality easily in this case via partial classes or defines, which does help to keep some of the workarounds for missing Silverlight functionality easy to maintain.
[Almost] whatever is possible in Silverlight, is possible in WPF, too. So if you have a VM working in Silverlight, it will [mostly] work with WPF.
From the other point of view, WPF offers richer possibilities, so you might want to use them in your WPF part of code. You can use the usual #ifdef Silverlight-like tricks.
Also, this question might be useful.
I have done one full project using WPF, and have (at least) a pretty good grasp of the main concepts, like XAML, Databinding, and MVVM. We did everything "by hand"--we did not use an MVVM framework or third-party tools. All XAML was written by hand as well (no Blend).
The new project I will start in a few weeks is pretty heavy-duty Silverlight, and I'm looking to get up to speed as quickly as possible. However most of the articles I've read on getting started with SL focus on XAML and databinding. Since my introduction to these concepts is still very fresh in my memory, I can certainly understand why these tutorials would spend a lot of time on these subjects--the learning curve can be very steep. However these are concepts that I am already familiar with, and find myself having to wade through a lot of covered ground to learn anything new and compelling.
So what I'm looking for are advice on what I need to learn and understand to go from being a journeyman WPF'er to a journeyman Silverlight'er. This can be in the form of:
General Advice
Key Differences
Rules of Thumb
Resources/Links ("A WPFer's Guide to
Silverlight" would be perfect :)
Major Pitfalls/Things to Watch Out For
Thanks in advance for any insight.
Rob Eisenberg (creator of Caliburn and Caliburn Micro) has a series of blog posts that talks about porting a WPF application to Silverlight. This may give you some insight into some of the framework differences.
Day 1
http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/25/porting-nhprof-from-wpf-to-silverlight-day-1.aspx
Day 2 http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/29/porting-nhprof-from-wpf-to-silverlight-day-2.aspx
Day 3 http://devlicio.us/blogs/rob_eisenberg/archive/2010/03/31/porting-nhprof-from-wpf-to-silverlight-day-3.aspx
Day 4 http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/01/porting-nhprof-from-wpf-to-silverlight-day-4.aspx
Day 5 http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/02/porting-nhprof-from-wpf-to-silverlight-day-5.aspx
Day 6 http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/02/porting-nhprof-from-wpf-to-silverlight-day-6.aspx
Day 7 http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/02/porting-nhprof-from-wpf-to-silverlight-day-7.aspx
Day 8 http://devlicio.us/blogs/rob_eisenberg/archive/2010/04/02/porting-nhprof-from-wpf-to-silverlight-day-8.aspx
Some other thoughts off the top of my head:
Binding defaults to One-Way
No DynamicResource
TabControl is fairly different
No ability to define implicit DataTemplates for types
No CoerceValue in Dependency Properties
Event routing is very basic
No built-in command structure. You have the ICommand interface, and ButtonBase controls have a Command property, though there's no class that implements the ICommand interface.
Missing x:Static, x:Type
All service calls need to be on a different thread than the UI thread. This essentially requires you to learn / implement async programming strategies. See here and here.
As was mentioned, it's a different framework so not all libraries are available to you. Example: there is no XmlDocument - you have to use XElement (which is arguably better, though even so)
The Navigation framework is totally different than WPF. Stay away from it. It will only cause you pain. ;]
Several of the Controls that you find in the core framework in WPF you'll find in the Silverlight Toolkit. Download it, you'll need it.
No built-in Triggers, though can use behaviors / actions provided in the Blend SDK (which essentially gives you the same thing)
If you need to interact with a database, it will have to be through services hosted somewhere, or through COM (which means Silverlight 4 OOB with Elevated Permissions).
I disagree with Kevin in that testing is actually fairly easy and all of the major testing frameworks and mocking frameworks support Silverlight. Where you run into issues is Code Coverage. The Microsoft Testing framework supports Code Coverage (Premium & above) or else you can use dotCover. I believe newer versions of nCover supports Silverlight though I'm not 100% certain. Use StatLight to run your Silverlight tests (regardless of testing framework) from the command line.
If you're not already using an IoC container pick one up. Autofac, Ninject, StructureMap, Unity, MEF. (Another bias of mine ;])
I would highly suggest looking into the available MVVM frameworks. This has cut down a significant portion of the framework code I typically have to write. The frameworks will probably only get you 80% of what you need, though that's 80% you didn't have to write yourself. I'm currently partial to Caliburn Micro, though most of the popular ones will give you what you need.
I'll add more if I think of more. Good luck in your journey!
I've really only done Silverlight for a real app...but one of my co-workers was a big WPF guy, and so I hear some of his gripes.
You're going to probably need to use a WCF service, etc., for asynchronous queries to your service/business layer
You're using a subset of the .NET framework, so you cannot include ANY of your class libraries as a reference, only Silverlight class libraries can be included. However, you can do stuff like having a 'link to existing file' in a silverlight library that links to a file in other libraries...as long as the code still compiles with only the reduced set. This is a bit of a maintenance nightmare, but if you are doing WPF & Silverlight with some of the same code, it will probably save you from a lot of replication. Make sure to make it a link to the file and not a copy of the file, or changes in one won't change the other.
Unit testing your ViewModels will not be as easy. Need to Moq your service and use a Silverlight unit testing project.
Some of the reduced functionality is annoying for WPF veterans.
I think our WPF guy complained about not being able to bind stuff like a CanExecute method as easily on his commands as he was able to do in WPF. He had to call the method directly from the command or something. (I've only gotten a chance to look at MVVM a little so far as I'm now on a different project :(, so not quite sure on that one).
Hope that helps a little.
I've been considering how you would write a business application in only F# with WPF. Here's my thinking of a general outline of how to go about it, but I'm looking for whether or not it will work:
Start with ADO.NET Entities to automatically generate a data access layer.
Since F# doesn't support partial classes, use F# Extension Methods to create a BLL that extends the entity objects with extra members (these will have to mutate the entities)
Instead of writing explicit ViewModels, write F# functions that build ViewModel objects on the fly using object expressions.
Write an F# function that uses Active Patterns and Decision Trees to build WPF Views on the fly, given ViewModel objects as input. It would also take care of setting up bindings between the View and ViewModel objects.
So, opening a form or page would involve executing a function to generate a ViewModel object instance, and then passing that to the function that builds a View from the ViewModel, and then setting that as the content of your Window. From that point on, it executes in a normal "mutable" MVVM way.
My knowledge of F# is still limited, so I may be going down the wrong rabbit hole here.
Question(s):
Will this work (in general), or not?
Is there a better way that you know of?
I don't know much about ADO.NET entities, or MVVM, or WPF, so I can't offer much critique of the technical ideas personally. It sounds like you have experience with all those technologies and know what's going on there. So my only commentary is that it sounds like there are too many new things to try all at once. To mitigate risks and increase the chance of success, I'd stage this across a few projects. E.g. maybe start with a traditional data layer using existing tools, and just try out your ideas for the F# View & ViewModel. And once you've worked out the kinks and gotten more comfortable with F#, then try tackling the data layer.
Do also be aware of
http://blogs.msdn.com/b/dsyme/archive/2010/07/29/some-f-project-templates-available-online.aspx
which include e.g. MVVM starter templates for F#, in case they provide any ideas/value (I am unclear how much your strategy departs from tradition to know if this will be helpful).
Here's another random link that may or may not be valuable:
F# and ADO.NET - idiomatic F#
This should work (tho I'm not sure about mutable entities, as I'm not an F# expert).
But my concern is the performance: F# uses a lot of recursion, especially in the case of decision trees, that will be a lot of work at runtime. I would consider pre-generating everything or a caching system. It's okay to generate at runtime using meta-programming, but why doing it every time when you can do it only once?
I really appreciate the question (and answers) we already have in “List of WPF functionalities that aren’t in Silverlight 3.” My allegedly new question narrows down the differences between WPF and Silverlight into the context of MVVM. Based on a Shawn Wildermuth MVVM sample project I downloaded from MSDN, I do see that, as of Silverlight 2, “Element Binding isn’t supported yet…” But this surely is just one detail and is this still the case? Is there a summary of MVVM-centered differences between WPF and Silverlight? Can we build our apps to move with more ease between the two technologies?
Update: Silverlight requires that calls to external resources be asynchronous whereas in WPF it can be synchronous or asynchronous. This requirement in Silverlight is due to the Web-based nature of the technology.
The pattern is identical, but the implementation may differ. Silverlight is missing some crucial pieces such as commands that mean you may need to put a little more effort into achieving an MVVM solution. However, at the end of the day, you'll still end up with M's, V's, and VM's.
Element binding is now available in Silverlight 3, along with a couple different options for implementing actions. There are behaviors, which are pretty easy to code, as well as commands if you use a framework like Prism (from the Microsoft Patterns and Practices team, not included in Silverlight by default). There's also the Visual State Manager, which is in Silverlight only right now, that handles a lot of the routine kinds of animations you might want if what you're doing is state-based.
Building apps to move between the two technologies is a different matter though. There are a number of XAML elements that are not supported on Silverlight (and some SL stuff not in WPF) and the underlying runtime is specifically kept small to facilitate web deployment, so there are and will continue to be a number of things missing. I don't think we'll see completely cross platform applications (code once, compile into both WPF and Silverlight without changes) in the near future and I think that in anything but the most trivial of examples the code revisions are going to be significant.
This doesn't mean that you can't apply MVVM to both or that the skillsets don't apply across both. If you are familiar with one, you're certainly 80% of the way there on the other immediately (that 20% can be tough though!) and understanding the pattern (I use databinding to get synchronization code out of the view and into the view model, I use commands/triggers/behaviors to remove actions from event handlers in the code behind of the view, etc.) means that you know what to do, even if how you do it is going to be a little different. From that perspective, I think we're about as close as we're going to get to achieving parity at a pattern level.
As for a summary of the MVVM pattern implementation differences between Silverlight and WPF, I haven't found one. Sounds like a good topic for a blog post from someone though...