I am currently working on a software using C# .NET and WPF with the MVVM pattern.
Though the software is almost done, I have been discussing our architecture for a long time and I would like to get your opinions/advices on the convention/good practices side.
The current architecture is as follows:
- Project/
- DataContext/
- Models/
- Engine3D/
- ...
- Utilities/
- Converters/
- Statics/
- ViewModels/
- Grids/
- Menus/
- Windows/
- ...
- Views/
- Grids/
- Menus/
- Windows/
- ...
Models folder:
Contains the Models from the MVVM pattern.
The Models folder is organized by feature, meaning that it has nested folders named after a feature or context, for example Models/Engine3D for every Model related to 3D.
We never append the "Model" word as a suffix, the files are named [Feature].cs
For example, Project.cs
, Model3D.cs
, Animation.cs
, etc...
Views folder:
Contains the Views from the MVVM pattern.
The Views folder is organized by WPF Control, meaning that it has nested folders named after a WPF Control, for example Views/Windows for every View related to a WPF Window, or View/Grids, etc...
The files are named [Feature][ControlType].xaml with:
- [Feature]: The "feature" implemented/described by the View, for example "CreateProject" for a feature creating a Project, Display3DModel for a Grid displaying a Model3D (using 3D libraries), etc...
- [ControlType]: The type of "xaml" control represented by the file, being a Window, a UserControl, a Grid, etc... As an example, a Window displaying the System Preferences would be called SystemPreferencesWindow.xaml, and a Grid holding the list of all the Projects would be ProjectsListGrid.xaml. For example, CreateProjectWindow.xaml, SystemPreferencesWindow.xaml, Display3DModelGrid.xaml, ProjectsListGrid.xaml
ViewModels folder:
Contains the ViewModels from the MVVM pattern.
The ViewModels folder copies the Views folder in terms of architecture, meaning that it has nested folders named after a WPF Control, for example ViewModels/Windows for every ViewModel related to a WPF Window, or ViewModels/Grids.
A ViewModel file has the same name as its related View file, with the suffix "ViewModel": the files are named [Feature][ControlType]ViewModel.cs with:
For example, based on View => ViewModel: CreateProjectWindow.xaml => CreateProjectWindowViewModel.cs, OpenProjectWindow.xaml => OpenProjectWindowViewModel.cs, etc...
DataContext folder:
Contains the DataContext files, ie. files related to a certain context in the software; these are classes that are neither ViewModels or Models, are mostly accessible "staticly" and correspond to a very specific context in the software execution flow so don't really belong in the Utilities folder. These classes are for example the Session class holding session values concerning the user like the web technologies' sessions.
Utilities folder:
Contains a set of files/classes tools of various goals :
- Definition classes, giving system mechanisms to the overall software such as ObservableObject.cs, DelegateCommand.cs and RelayCommand.cs which permit MVVM data binding, etc...
- Utilities/Converters folder: Converters classes...
- Utilities/Statices folder: Contains static operations classes taking an input and returning an output, for example FileOperations.cs, XWindow.cs (don't bother with the name, it's project's specific) that regroups System.Windows operations like InvokeWindow() and CloseWindow() so that it's easier to manipulate System.Windows in the code, Model3DImporter.cs which imports 3D Models very easily, SerializationManager.cs for serialization operations, etc...
Classes with constants:
Some classes need constants values and since these values must be accessed from pretty much everywhere in the code, we didn't store these constant values in the related classes but in a "sister" class.
These "sister" classes are as follows:
// The sister class
public static class Model3DConstants
{
private static readonly IList<String> supportedFileExtensions = ...
}
// The original class
public class Model3D
{
}
As I mentioned in the beginning of my message, I would like your ideas/advices on our architecture/naming conventions, because I am sure that we are missing something out but don't know what.
Are we doing the complete opposite of what should be done in a correct C# .NET MVVM software using WPF, what are the flaws and/or stuff that we should modify
Do not hesitate to participate in the debate neither or even ask me questions if I am unclear about the above description.