HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Caliburn.Micro nested ViewModels

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
micronestedcaliburnviewmodels

Problem

I am currently developing a small tool intended to help me keep track of the myriad of characters in my Stories.

The tool does the following:

  • Load the characters which are currently stored as json on the disk and stores them in a list, which is presented in the Shell via a ListBox.



  • If the user then opens a character the Shell, which is a Conductor.Collection.OneActive, opens a new CharacterViewModel, that derives from Screen.



  • The Character gets the Character that is going to be opened via the IEventAggregator message system.



  • The CharacterViewModel furthermore has various properties which are sub ViewModels which bind to various sub Views.



And here is my Problem:
Currently I initialize the sub ViewModels manually when the ChracterViewModel is initialized. But this sounds fishy to me and I am pretty sure there is a better way to do this, but I cannot see how I should do it.

Here is the code of the CharacterViewModel:

```
/// ViewModel for the character view.
public class CharacterViewModel : Screen, IHandle>
{
// --------------------------------------------------------------------------------------------------------------------
// Fields
// -------------------------------------------------------------------------------------------------------------------

/// The event aggregator.
private readonly IEventAggregator eventAggregator;

/// The character tags service.
private ICharacterTagsService characterTagsService;

// --------------------------------------------------------------------------------------------------------------------
// Constructors & Destructors
// -------------------------------------------------------------------------------------------------------------------

/// Initializes a new instance of the class.
public CharacterViewModel()
{
if (Execute.InDesignMode)
{
this.CharacterGeneralViewModel = new CharacterGeneralViewModel();

Solution

Comments

I need to comment on ...your comments. Really. NONE of the comments you have here are useful.

None of them.

Xml comments

This is rather unusual:

/// ViewModel for the character view.


Normally XML comments looks like this:

/// 
/// ViewModel for the character view.
/// 


That's also how the IDE sets them up automatically for you when you type /// (assuming Visual Studio), so having them on 1 line seems like you're fighting your IDE. Embrace it!

The purpose of XML comments is to provide documentation, specifically for the public API. This:

/// The event aggregator.
private readonly IEventAggregator eventAggregator;


...is overkill useless clutter. If you need a comment that says "The event aggregator" for a private field called eventAggregator of type IEventAggregator, ... same here:

/// The character tags service.
private ICharacterTagsService characterTagsService;


Banner comments

This is rather annoying:

// --------------------------------------------------------------------------------------------------------------------
// Fields
// -------------------------------------------------------------------------------------------------------------------


Kill it, with fire. Burn. The maintainer that cannot tell a field from a property shouldn't be maintaining your code. The only thing worse you could have done, is wrap them in a #region Fields.

This

I find the this qualifier adds to the clutter, although here it's needed:

public CharacterViewModel(IEventAggregator eventAggregator)
    : this()
{
    this.eventAggregator = eventAggregator;
    this.eventAggregator.Subscribe(this);
}


...but only because eventAggregator isn't called _eventAggregator. All other instances of this can be removed.

That said...

Constructor chaining

You have it reversed: the parameterless/default constructor should be calling the parameterized constructor, not the other way around:

public CharacterViewModel()
    : this(null)
{
    // ...
}


Why are you injecting an IEventAggregator (which is good), but instantiating CharacterGeneralViewModel and CharacterMetadataViewModel? They could be constructor-injected as well.

Code Snippets

/// <summary>ViewModel for the character view.</summary>
/// <summary>
/// ViewModel for the character view.
/// </summary>
/// <summary>The event aggregator.</summary>
private readonly IEventAggregator eventAggregator;
/// <summary>The character tags service.</summary>
private ICharacterTagsService characterTagsService;
// --------------------------------------------------------------------------------------------------------------------
// Fields
// -------------------------------------------------------------------------------------------------------------------

Context

StackExchange Code Review Q#61882, answer score: 5

Revisions (0)

No revisions yet.