Abstract CommandClass for IExternalCommand

Abstract CommandClass for IExternalCommand

jeff
Collaborator Collaborator
795 Views
2 Replies
Message 1 of 3

Abstract CommandClass for IExternalCommand

jeff
Collaborator
Collaborator

We have starting using Revit for about 2 weeks and most of 1 week was spent on another project that uses AutoCAD.

So I am just getting familiar with Revit and have only looked at API briefly, and without a good strong understanding of the fundamentals of the API it hard to know what are good parts to abstract out for reusable libraries.

 

The limited examples and templates I have seen implicitly implements IExternalCommand.

 

I was wondering why not explicitly implement IExternalCommand in base classes for common command functionality?

 

So I guess the main question would be does Revit always call Execute through IExternalCommand interface?

 

If I am not being clear enough would the below example be a safe practice to use?

 

This might be common practice I just have not seen it mentioned or used in the limited examples I have seen.

 

This example only saves a little typing and just assigns some properties to commonly needed objects in a command.

 

Base Command class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit.DB;

namespace Autodesk.Revit.UI
{
    public abstract class CommandClass : IExternalCommand
    {
        protected ExternalCommandData CommandData { get; private set; }
        protected UIApplication UIApp { get; private set; }
        protected Document Doc { get; private set; }
        Result IExternalCommand.Execute(ExternalCommandData commandData, ref string message, DB.ElementSet elements)
        {
            this.CommandData = commandData;
            this.UIApp = CommandData.Application;
            this.Doc = UIApp.ActiveUIDocument.Document;
            return this.Execute(commandData, ref message, elements);
        }
        public abstract Result Execute(ExternalCommandData commandData, ref string message, DB.ElementSet elements);
    }
}

 

So if you took the example Lesson 1 from My First Plug-in Training and inherited class above it would be changed to

[TransactionAttribute(TransactionMode.Manual)]
[RegenerationAttribute(RegenerationOption.Manual)]
public class Lab1PlaceGroup : CommandClass
{
    public override Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
    {
        //Define a Reference object to accept the pick result.
        Reference pickedRef = null;

        //Pick a group
        Selection sel = UIApp.ActiveUIDocument.Selection;
        pickedRef = sel.PickObject(ObjectType.Element,
          "Please select a group");
        Element elem = Doc.GetElement(pickedRef);
        Group group = elem as Group;

        //Pick a point
        XYZ point = sel.PickPoint("Please pick a point to place group");

        //Place the group
        Transaction trans = new Transaction(Doc);
        trans.Start("Lab");
        Doc.Create.PlaceGroup(point, group.GroupType);
        trans.Commit();

        return Result.Succeeded;
    }
}

 

The one quick test I did worked and that is not saying much unless it would Always work.

 

With limited knowledge I do not know what functionality would be useful to place in class and just wondering if it would be safe to explicitly implement IExternalCommand in base class for Revit to call Execute.

 

You can also find your answers @ TheSwamp
0 Likes
796 Views
2 Replies
Replies (2)
Message 2 of 3

ollikat
Collaborator
Collaborator

From my own experience point of view I would say that base class definitelly can be used. Especially if you are gointo to do a bit bigger application where multiple external commands are needed. Then I think it's almost oblicatory to have some common place for certain initialization codes etc. which are common to most of the cases.

 

I would say that Revit always uses this interface. Of course there are also IExternalApplication, IUpdater etc. interfaces but they never replace IExternalCommand interface.

0 Likes
Message 3 of 3

jeff
Collaborator
Collaborator

Thanks ollikat,

 

The reason I ask is its typically considered a bad practice to explicity implement a Interface as in the example above unless it will always be called through the interface.

 

http://msdn.microsoft.com/en-us/library/vstudio/ms229034(v=vs.100).aspx

You can also find your answers @ TheSwamp
0 Likes