[NOTE: This post is part of a blog series, the start of which is here.]

 

Happy new year! :)

 

Recently, I’ve had a few questions around how UML Profiles are supported in VS 2010, so figured I’d start the new year with a post about that.

By now, you’ve all got the Beta2 version of VS 2010. This post will discuss some basics that you need to know about profiles, and why they matter. My next post will discuss how to create your own.

Let me first start by pointing out the excellent documentation around this feature, found here. Almost everything I’m going to discuss is found there and the various references therein. I’m just going to hilite the essence of the feature.

What the heck’s a Profile?

A profile, as defined by the UML spec, is a

“…mechanisms that allow metaclasses from existing metamodels to be extended to adapt them for different purposes.”

( Clear as mud right? :) Think of a profile as a container of new meta data with all the constraints that restrict or allow that new meta data to be applied to particular types in your UML model. What this then allows you to do is apply that Profile, and then apply a stereotype to a particular element type that then exposes some new fields or what have you. In its simplest form, this would result in some new fields in the property editor for that type that you can then manipulate. In a more complex form, this could restrict what relationships a type could play in, etc.

A quick example to drive this home.

Here’s a shot of a property editor for a selected class:
image

Notice there are no properties under the Stereotypes property, but if I apply a stereotype, suddenly a bunch of new properties appear, as seen below:
image

I’ve circled the changes that have occurred to that class after applying that stereotype. Lots of new properties plus an annotation on the class element on the diagram indicating that the stereotype called C# class has been applied.

Applying a Profile

You can apply any profile, be it a custom made or standard profile that ships in the box, on any UML Package or package derived type. So for example, if you create a UML Project and select the root element in the UML Model Explorer, you’ll notice two things: 1) That the project element is actually a UML element of type Model ( which is ultimately derived off of Package ), and 2) that two standard profiles are already applied on that element.

 image

We will ship three profiles in the box by the time we ship VS 2010 Ultimate. Two profiles that are standard to UML ( Standard Profile L2 and Standard Profile L3 ) and one specific to C# ( named, surprisingly enough, C# Profile :) ).

You apply ( or remove ) a profile to a Package ( or package derived type like Model ) by selecting that element and setting the profile property. So if I select the “ProfileExample” in the UML Model Explorer as seen above, here’s what the Profile property looks like with the currently available values:

image

Notice that the values are check box entries, allowing you to check or uncheck that profile. Apply or remove, your call.

Profile applied, now what?

Once you’ve applied a prototype to a package, a number of new stereotypes become available to any and all contained elements in that package dependent on the type of the element. As I mentioned earlier, by default the two standard UML profiles are automatically applied to the Model element that represents your modeling project. So in our example above, when I select “ProfileExample” and then expand the Stereotypes property, here’s what I see:

image

If I selected “Sub Package One”, which is contained by “ProfileExample”, I see this:

image

Notice how “metamodel” and “systemModel” are not present in the list. That is because the “Sub Package One” element is a UML Package, where as the “ProfileExample” element is a UML Model. The list of stereotypes is completely dependent on element type. To further the example, if I select “Class1” contained in “Sub Package One”, I see this:

image

And to just make sure everyone is on the same page, if I go back up to the “ProfileExample” element and uncheck every profile, then select “Class1” again, I will get no stereotype options.

Stereotype applied, now what?

Once you apply a stereotype to a particular element, a number of things can happen. If you look back up to the second image in this post, I’ve applied the C# Class stereotype to “Class1”. That results in a stereotype adornment on the element itself, as well as a number of properties that are now made available on the element.

Important to note that these new properties are now made available to any element that the stereotype is applied to, but the individual properties exposed by those stereotypes ( e.g., the “Is Partial” property for the “C# Class” stereotype ) and the values associated with them are stored on the individual instance of the applied element.

Ok, got it, but why does all this Profile / Stereotype stuff matter?

Fundamentally, this is just another way to extend the semantic meaning of your models. It allows you to add more information to your models without having to invest in something more powerful ( like building a new DSL ) when all you want is a few boolean fields added to your elements! And once that new data is there, you can also lean on that added information in other scenarios, such as controlling how code is generated from the model based on applied stereotypes and the values therein.

With the extension capabilities in the product, this becomes quite trivial. For example, if you follow the steps outlined in Peter’s post here, you can quickly add a menu item that manipulates those stereotypes of selected elements. The code below adds a menu item to the UML class diagram, looks for selected UML classes, and pulls the stereotype that matches the “C# class” stereotype if applied:

( NOTE 6/2/2010: The code below was against the Beta2 build.  The name of the assembly changed from the Beta2 build to the RC build. Please use the Microsoft.VisualStudio.ArchitectureTools.Extensibility.dll in %programfiles%\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies. Everything else should work fine. )

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Uml.Extensions;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Modeling.ExtensionEnablement;
using Microsoft.VisualStudio.Uml.Presentation;
using Microsoft.VisualStudio.Uml.Classes;
using System.Windows.Forms;

namespace ExampleUMLExtensions
{
    [Export( typeof( ICommandExtension ))]
    [ClassDesignerExtension]
    public class MenuGesture : ICommandExtension
    {
        // IClassDiagramContext 
        [Import]
        public IDiagramContext Context { get; set; }

        public void Execute(IMenuCommand command)
        {
            var selectedClasses = Context.CurrentDiagram.GetSelectedShapes<IClass>();

            var stereotypeInstance = (from shape in selectedClasses
                                    where shape.Element is IClass
                                    from stereotype in shape.Element.ApplicableStereotypes
                                    where stereotype.DisplayName == "C# class"
                                    select stereotype).Fist();

            // Party on the Properties property collection of the found stereotype instance
            // ...
            
        }

        public void QueryStatus(IMenuCommand command)
        {
            command.Enabled = true;
            command.Visible = true;
        }

        public string Text
        {
            get { return "Manipulate Stereotype";  }
        }
    }
}

Next time…

Like I mentioned at the start of this post, next time I’ll dig a little deeper into what is needed to create your own profile, and how you can make that profile available to your friends and neighbors. :)

Cameron