MVVM and Visual Studio’s UserStory Extension

Intro

I have improved my software development practice by building a Visual Studio extension. This extension has boosted my productivity by enabling me to rapidly generate user story modules to support my emergent design practice.

Bizmonger Extensions

One extension that I have built to support my development efforts is the UserStory project template. This project template can be downloaded from the Visual Studio gallery or from Visual Studio’s Extensions and Updates dialog.

To download the extension from Visual Studio perform the following:

  1. Select Tools | Extensions and Updates.
  2. Select the Online tab.
  3. Ensure the Visual Studio Gallery is selected.
  4. Type “Bizmonger” in the search bar.
  5. Install both “Bizmonger.UserStory” and Message Snippet

Extensions_dialog

Bizmonger.UserStory

Bizmonger.UserStory is a portable class library that serves as an individual module for an arbitrary user story. I wrote this extension to support architectures that are organized by user story modules instead of relying on obscure folder names like “Views”, “ViewModels”, and “Model”. For example, when viewing projects within a solution that supports a user story driven architecture, one would observe projects that are actually based on the user stories that the software was intended for. For example, there could be a module called “Login”. Another module could be called “ViewProfile”. Thus, there could be another module within the solution called “EditProfile”.

I recently wrote an Android app in Xamarin.Forms using the described pattern:

stories

That app supported two user stories. One user story involved enabling a user to choose from a menu of clips so that he/she could place textual content on a clipboard and then paste the content onto a text message or email. That user story was called the ViewMenu module. The other user story involved editing content in order to update and archive the content for later use. This was done in the EditContent module of the app.

Adding a UserStory Module

With the Bizmonger.UserStory extension installed:

  1. Select File | New | Project.
  2. Type “UserStory” in the search bar.
  3. Select the UserStory project and assign it the name: ViewMenu.
  4. Click OK button.

new_userstory

When the project gets created you should observe the following project structure:

added_userstory

NOTE: I created a folder called “Stories” add moved the project under it.

Composite ViewModel

In the project, you will observe an expandable view-model. I call this type of view-model a Composite ViewModel. A Composite ViewModel is a set of partial view-model classes. Each partial class of the view-model isolates a specific responsibility of the view-model. I discovered this structural pattern after growing tired of maintaining monolithic view-models. I was just fed-up with having to scroll up and down the editor of a view-model class just to either debug or extend it.

The isolated responsibilities that make up a composite view-model are the following:

      • ViewModel (state)
      • ViewModel.commands
      • ViewModel.internal

Messages
The Messages class contains user-defined message ids that can be placed on the MessageBus to dispatch notifications to decoupled subscribers of a message.

ViewModel
The composite view-model parent node is responsible for initializing commands and conveying state. Specifically, it registers subscriptions, instantiates commands, and conveys state.

    public partial class ViewModel
    {
        public ViewModel()
        {
            MakePromises();
            ActivateCommands();
        }

        public bool DidSomething { get; set; }
    }

ViewModel.commands

ViewModel.commands isolate the behavior of the view-model from its state.

    public partial class ViewModel
    {
        public ICommand DoSomething { get; set; }
        void ActivateCommands() => DoSomething = new DelegateCommand(obj => _messagebus.Publish(Messages.REQUEST_SOME_ACTION));
    }

ViewModel.internal
ViewModel.internal manages internal state through its encapsulated logic.

    public partial class ViewModel
    {
        MessageBus _messagebus = MessageBus.Instance;

        void MakePromises()
        {
            _messagebus.Subscribe(Messages.REQUEST_SOME_ACTION, RespondToSomeAction);
        }

        void RespondToSomeAction(object obj)
        {
            DidSomething = true;
        }
    }

Adding a Unit Test

test_dialog

  1. Select File | New | Project.
  2. Select Unit Test Project.
  3. Name the test project: “ViewMenu.Tests”.
  4. Observe the “ViewMenu.Tests” project is added to the solution.
  5. In solution Explorer, rename “UnitTest1.cs” within the test project to “_ViewMenu.cs”
  6. Add a reference to the ViewMenu project
  7. Replace the following unit test:
    [TestClass]
    public class _ViewMenu
    {
        [TestMethod]
        public void TestMethod1()
        {

        }
    }

With:

    [TestClass]
    public class _ViewMenu
    {
        [TestMethod]
        public void do_something()
        {
            // Setup
            var viewModel = new ViewModel();
            var doSomething = viewModel.DoSomething;

            // Test
            doSomething.Execute(null);

            // Verify
            Assert.IsTrue(viewModel.DidSomething);
        }
    }

Go ahead and run the test.

Conclusion

In conclusion, I have improved my software development practice by building a Visual Studio extension. This extension has boosted my productivity by enabling me to rapidly generate user story modules to support my emergent design practice. Thus, I have shared a tutorial to get developers started with this visual studio extension. I then provided additional steps on how to unit test a user story module. I welcome feedback.

NOTE:

Scott Nimrod is fascinated with Software Craftsmanship.

He loves responding to feedback and encourages people to share his articles.

He can be reached at scott.nimrod @ bizmonger.net

Advertisements
2 comments
  1. The user story project organization is intriguing. How do you handle the organization of shared functionality?

    • Hi gregsdennis. Shared code is extracted into a separate library. I have provided screen shots on related articles that I’ve wrote. Here’s a link.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: