Modeling: Deriving and Extending Classes

Modeling in the System Center common platform involves defining new classes, properties on those classes, and relationships between those classes.  In a previous post, I showed you how to define a new derived class in a management pack to extend the Service Manager database.  In this post, I’ll describe the difference between deriving a new class from an existing class and extending an existing class.  Class extension is a new feature in the 1.1 version of the management pack schema and infrastructure which ships with Service Manager 2010.  It will also be available in the future releases of Operations Manager and System Center Essentials that come after this calendar year.


Let’s work with a concrete example – the Incident class.  The model of Incident looks like this:


Incident Model


Please note: this is a snapshot of the model at the point in time that I wrote this blog article.  It may not necessarily represent what is in Beta 1 or what will finally be released.


The Incident class inherits its properties (and relationships although they are not shown) from each of its parent classes such as System.Entity,  System.WorkItem, and System.WorkItem.TroubleTicket.  For example, all incidents have a Title, ActualStartDate, CreatedDate, etc. inherited from the System.WorkItem class.  The idea is that all properties which are common to all kinds of work items (change requests, problems, incidents, etc.) are defined on the System.WorkItem class.  All work item classes then derive from there and inherit those common properties.


There are several kinds of incidents in Service Manager as indicated in this diagram:


 


 Incident Model Derived Classes


As you go down an inheritance hierarchy you get more and more specific in describing what you are talking about.  We also call this specialization.


The way you declare a new class in MP XML that inherits from another class is like this:


<ClassType ID=Microsoft.SystemCenter.WorkItem.SCOMIncident Accessibility=Public Base=System.WorkItem.Incident />


 


The Base attribute indicates which class you are deriving from.


Now, let’s say that you wanted to track a new property about incidents such as the amount of time worked on the incident.   Let’s also assume you want to track this property for all kinds of incidents – regular incidents, SCOM incident, SCCM DCM incidents, and any other future kinds of incidents which may be derived from incident.  Since Microsoft shipped the System.WorkItem.Incident class in a sealed MP nobody can change it directly to add any new properties.  However, now with the 1.1 version of the MP schema and infrastructure, you can extend sealed MP classes to add new properties by defining a class extension in a different MP that references the sealed MP that contains the class you want to extend.


To extend a class, you declare a new ClassType and set the Base attribute to the ClassType ID you want to extend and set the Extension attribute to true like this:


<ClassType ID=Woodgrove.Incident.Extension Accessibility=Public Base=IncidentLibrary!System.WorkItem.Incident Extension=true>


<Property ID=MinutesWorked Type=int />


</ClassType>


Now this new property – MinutesWorked – will be available on all objects of the System.WorkItem.Incident class and any object of any class that derives from System.WorkItem.Incident.  What we have effectively done is add a property to System.WorkItem.Incident like this:


 Incident Model Extended


There is one other important thing to note here.  Typically the classes that you want to extend will be contained in sealed management packs.  In this case, you can only extend those classes which are marked as Accessibility=Public.  Classes which are marked Accessibility=Internal  may only be extended within the same MP (and I have no idea why you would do that 🙂 ).  Most importantly, when you extend a class you need to create a reference in the Manifest section of the MP that contains the class extension which points to the MP that contains the class you are extending.  In the example, above you can see that Base=IncidentLibrary!System.WorkItem.Incident uses an MP reference which is aliased as “IncidentLibrary”.  An MP alias is the part before the exclamation point in MP reference syntax.  You can create a MP reference in your MP like this:


<Reference Alias=IncidentLibrary>


<ID>ServiceManager.IncidentManagement.Library</ID>


       <Version>1.0.3113.0</Version>


<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>


</Reference>


Make sure that you have the ID, version, and public key token of the MP you are referencing correct and that the MP you are referencing is imported prior to importing the MP which contains your extension.


Once your extension MP is imported the database schema will be extended automtaically to create a new table for your extended class:



And the view that returns incidents from the database will be automatically updated to return this additional extended property:



So – the complete MP that extends the System.WorkItem.Incident class with a new property for MinutesWorked looks like this:


<?xml version=1.0 encoding=utf-8?>


<ManagementPack ContentReadable=true SchemaVersion=1.1 xmlns:xsd=http://www.w3.org/2001/XMLSchema xmlns:xsl=http://www.w3.org/1999/XSL/Transform>


  <Manifest>


    <Identity>


      <ID>Woodgrove.Incident.Extension</ID>


      <Version>1.0.0.0</Version>


    </Identity>


    <Name>Woodgrove Incident Extension</Name>


    <References>


      <Reference Alias=IncidentLibrary>


        <ID>ServiceManager.IncidentManagement.Library</ID>


        <Version>1.0.3113.0</Version>


        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>


      </Reference>


    </References>


  </Manifest>


  <TypeDefinitions>


    <EntityTypes>


      <ClassTypes>


        <ClassType ID=Woodgrove.Incident.ExtensionClass Accessibility=Public Base=IncidentLibrary!System.WorkItem.Incident Extension=true>


          <Property ID=MinutesWorked Type=int />


        </ClassType>


      </ClassTypes>


    </EntityTypes>


  </TypeDefinitions>


  <LanguagePacks>


    <LanguagePack ID=ENU IsDefault=true>


      <DisplayStrings>


        <DisplayString ElementID=Woodgrove.Incident.ExtensionClass” SubElementID=MinutesWorked>


          <Name>Minutes Worked</Name>


        </DisplayString>


      </DisplayStrings>


    </LanguagePack>


  </LanguagePacks>


</ManagementPack>


Remember, if all of this XML seems a bit intimidating to you, we will be providing a Management Pack authoring tool that will make all of this very easy to do – no XML writing required.

Woodgrove.Incident.Extension.xml