Cascading Dependencies in System Center 2012 Service Pack 1 (SP1)
Applies To: System Center 2012 R2 Orchestrator, System Center 2012 SP1 - Orchestrator
The information in this topic applies only to System Center 2012 SP1.
The use of cascading dependencies greatly simplifies the user experience when configuring complex activities by reducing the amount of information from which the customer selects to only what is most relevant. You can also use this feature to include or exclude properties from display based on the selections in other properties. This is useful when certain properties either must be or cannot be used together.
Creating Activities that have Cascading Dependencies
The cascading dependencies feature is only available when developing custom activities using the Orchestrator 2012 SP1 (7.1) SDK. You cannot create activities that have cascading dependencies from within the Command-Line Activity Wizard. This is because the potential array of configuration options is quite large, and will vary widely from situation to situation. The only way to approach this complexity is to allow full control of it via developer code. In other words, it's up to the activity developer to determine how cascading dependencies will function in any given activity. Also, given its dynamic nature, the cascading dependencies feature is only available when your activity follows the imperative design model (extending from the IActivityWithRedesign interface). Since the declarative model defines a more static design, it is not appropriate for cascading dependencies.
Implementing cascading dependencies in a custom activity is relatively simple. It requires the following steps:
Define the Activity as One that Supports Cascading Dependencies
Define the Process that Occurs when a Property with Dependencies is Modified
Define the Input Properties that have Dependencies
Define the Activity as One that Supports Cascading Dependencies
With previous custom activities, you defined your activities as inheriting from IActivity. In order for Orchestrator to understand that this new activity will have the ability to perform cascading dependencies, it needs to inherit from IActivityWithRedesign. Here is some sample code for the class implementation:
class CascadingActivity : IActivityWithRedesign
{
}
Define the Process that Occurs when a Property with Dependencies is Modified
Once you define the inheritance from the previous step, you'll see errors that your activity does not implement all of the required methods for the interface. In order for this activity to function, you'll need to implement the following methods (method signatures shown):
public void Design(IActivityDesigner designer)
{
}
public void Redesign(IActivityDesigner designer, IRedesignRequest request)
{
}
public void Execute(IActivityRequest request, IActivityResponse response)
{
}
You should already be familiar with Design and Execute. These methods are required when you inherit from the IActivity interface. However, the Redesign method is new. It's important to understand when these methods are called so that you can appropriately handle how the activity properties are displayed.
When the activity loads for the first time or when the connection setting for the activity (if there is one) is modified, the Design method is called. Think of this as the initialization of the form, where you would display the initial property or set of properties needed to determine the other cascading dependencies. In the Design method, you may choose to only display one property.
When any property marked with the .WithRedesign() method is modified, the Redesign method is called. This allows you to modify the list of properties displayed dynamically depending on the choices the user makes. Unlike the Design method, the parameters to the Redesign method include an IRedesignRequest object that contains a list of all the active inputs and their values, along with the name of the property that changed. Usage of this object is discussed in more detail below.
When the activity is saved and then re-opened at some later time, the Redesign method is called so that you can ensure all of the right properties are again placed onto the form. The name of the property that changed is empty to indicate that the method is being called from the form being re-opened.
Define the Input Properties that have Dependencies
In order to designate a property as one that causes Redesign to be called, it must be marked with the .WithRedesign() method. Here's an example:
designer.AddInput("Module Name").WithListBrowser(names).WithRedesign();
An additional restriction is that the user cannot type any information in to this property or use published data. They must select from a list box or browser of some sort. This is by design to allow developers to properly define output properties and core activity logic at design time and not be concerned with dynamically determining these things at runtime. This restriction means that you should use cascading dependencies for high-level properties that are not likely to be ones customers would want to change dynamically at runtime.
More Details about the Redesign Method and Implementing Cascading Dependencies
When the Redesign method is called, it's important to know that the activity form is once again a blank slate and that unless you add properties to it, it won't have any once your Redesign method is finished. So when creating the code for the Redesign method, keep this process in mind:
Figure out what property changed (if any).
This can be done by examining the request.ChangedPropertyName property. If it's empty, that means the form was just opened from a previously-saved state.
Read in the existing property names and values.
You get these from the request.RedesignInputs property. This property is an IInputCollection (a collection of KeyValuePair<string, IRuntimeValue>), that is a list of property names and their respective values.
Design the input and output properties for the form.
Based on the property that changed and the current values of the inputs, you can decide how to add more input or output properties to the form. For example, the PowerShell cmdlet activity scenario above might have this kind of pseudocode logic in the Redesign method:
if (string.IsNullOrEmpty(request.ChangedPropertyName)) { Add module names property and set default value to current value Add cmdlet names property and set default value to current value Add parametersets property and set default value to current value Add remaining cmdlet parameters and set default values to current values return } switch (request.ChangedPropertyName) { case ("Module Name"): Add (retain) module names property and set default value to current value Add cmdlet names property based on module name selected break; case ("Cmdlet Name"): Add (retain) module names property and set default value to current value Add (retain) cmdlet names property and set default value to current value Add parametersets property based on module/cmdlet selected break; case ("ParameterSet"): Add (retain) module names property and set default value to current value Add (retain) cmdlet names property and set default value to current value Add (retain) parametersets property and set default value to current value Add remaining cmdlet parameters as required or optional properties based on module/cmdlet/parameterset break; default: break;
As you might have noticed, with each successive new property being added to the form (based on changes to a parent property), all of the parent properties are being re-added to the form as well. Remember that this is a blank slate each time, and if you don't re-add the properties, they will disappear from the activity when it gets redesigned.
Also, setting the value of the property if it existed before is easy. Use .WithDefaultValue(<previousvalue>) on the input property, and that value will appear as the selected value the when the form is redisplayed.
Keep in mind that your activity may have varying numbers of cascading properties depending on what values the user chooses. In the example above, if the cmdlet has only one parameterset, you may choose not to display the parameterset property at all and simply select the only value by default, skipping that extra step for the user and displaying the parameters for the cmdlet.
When developing custom activities using cascading dependencies
Be aware of the time it takes to perform each Redesign. If the user selection triggers a call to a remote computer to look up information from the system, SQL, WMI or other data source, each call made will take some length of time to complete, which means the user is waiting for the activity to be repainted. Users are accustomed to seeing the form repaint immediately, so cascading dependencies will introduce a new concept of waiting. The more waiting they have to do, the less enjoyable the experience with your custom activity.
- When gathering the information needed to redesign the form will take more than a second or two, consider displaying a popup message box that tells the user what's going on, and potentially includes a progress bar. The SDK example for cascading dependencies has an example of this. This includes the instances where the Redesign method is being called when an activity is opened from a saved state.
Be cautious that you do not over-complicating the user experience by having too many cascading dependencies, especially if each one results in a time delay while the information is being retrieved and filtered. While you can have any number of properties that trigger the Redesign method, it's probably best to keep the number at five or less.
IPs created using the Command-Line Wizard and IP Wizard from OIT 7.0
If no changes needed to the IP, then you can simply install the IP as is. There is no need to repackage the IP for 7.1.
If changes are needed to the IP, you can continue to use the 7.0 version of the Toolkit for modifying and repackaging the IP.
If changes are needed to the IP and you have only the 7.1 version of the Toolkit available, you must recompile the assembly using the 7.1 version of the Command-Line Wizard and then repackage the IP using the 7.1 version of the IP Wizard. This is the same procedure that was required when upgrading from Opalis 6.3 to Orchestrator 2012 defined in the section titled "QIK CLI Activity Migration" in the Command Line Activity Wizard documentation.
IPs created via custom code against the 7.0 SDK
If no changes needed to the IP, then you can simply install the IP as is. There is no need to repackage the IP for 7.1.
If changes needed to the IP, but you do not need cascading dependencies or other changes implemented in version 7.1, then you can continue to utilize version 7.0 of the Toolkit for creation and packaging.
If you want to implement any of the features or changes found in version 7.1 of the Toolkit, you must modify the project reference to the Microsoft.SystemCenter.Orchestrator.Integration.dll file and recompile, and then repackage using the 7.1 version of the IP wizard. This is similar to (but not as complicated as) the requirements for upgrading from Opalis 6.3 to Orchestrator 2012 outlined here: Migrating QIK API Custom Activities
Note
If you try to open an assembly in the Integration Pack Wizard version 7.1 and it has references to the previous version of the Toolkit assemblies, an error will be displayed.