No Inheritance and No Strong Naming

Here are two little items of general long-standing interest that just came up in a Revit API discussion forum:

These two issues sometimes come as a surprise to developers experienced in

OOP
and other CAD system programming.

However, there are good reasons for both.

Here are the detailed explanations:

Why You Cannot Derive a New Class From FamilyInstance

Question: I would like to extend some classes provided by the Revit API, e.g. by inheriting from them and implementing my own derived classes.
I think it would be very useful to specialise some classes, like FamilyInstance.

Answer: Do you have any particular goals behind inheriting from FamilyInstance?
What would you like to be able to accomplish that inheritance or extensibility would allow?

Question: I created an add-in that uses a Revit family to delimitate an area.
I call it a ‘marker’ and can identify it by its symbol.
It helps identify where and how other element need to be placed.

Having a public constructor will allow us to inherit our marker class from FamilyInstance.
In fact, a marker IS a family instance, with just some other properties.
Now we have to copy some data from the FamilyInstance to the marker it belongs to, like its unique id, location, rotation and so on.

It would be easier for us to serialize and deserialize the class being sure correct data is copied to the database.

Also the code understandability would be improved, since calling new FamilyInstance(x,y,z, rotation, symbol) is much more obvious than calling a static constructor.

Any programmer would expect that calling a constructor such as this would drop a new instance into the project.

Answer: Thank you for the clarification.

The structure of Revit and it’s API is a little bit different than I think you expect, so this is not going to work as well as you hope.

Revit API objects are managed wrappers around native C++ objects used by Revit’s UI and database.
Therefore, a FamilyInstance in the API does not actually contain the properties you see – the API code accesses them through the matching native object’s members. So extending our managed classes would not actually allow for new data to end up in the Revit file during serialization – we don’t know how to get the data from your inherited class.

We don’t supply public constructors for many of these objects for precisely this reason – much more needs to happen than just building the object and populating the x, y, z, etc. – the document tables need updating, dependent elements must be added, relationships established etc. So this is what we have methods like NewFamilyInstance and, for our newer element creation calls, static creation methods taking the document and necessary parameters.

If you want to get additional serialized data onto a Revit element, you should look at

Extensible Storage
in the Revit API.

If you want to make code easier to write and want to ‘add’ additional members to our classes (so you could have a call to a FamilyInstance.GetMarker method or something like that), you can look at

C# extension methods

however, adding such methods will not allow additional data to be stored in those classes unless you implement these members using Extensible Storage.

Why the Revit API Assemblies are not Strongly Named

Question: Looking at the Revit API documentation, I do not see any mention of

strong naming
.

Is there a particular reason for that?

This can cause several security issues, and some customers may require us to sign our Revit add-in assemblies, which we currently cannot do.

Answer: Yes, this is true.
There are good reasons for this.

Here is an explanation why

you cannot sign your AutoCAD .NET plug-in with a strong name
.

It covers all the technical details and includes some workarounds, which all apply to Revit add-ins as well.

Note that Microsoft modified the strong name verification system so that

some security measures related to signatures are now bypassed
by
default.

Wise Words

I hope these explanations make sense.

There are quite a few surprises lurking in the Revit API and the entire Revit product paradigm for unwary developers experienced in other less parametric and BIM oriented CAD systems, as we have already repeatedly seen in the past:

In fact, as I often point out, one of the hardest tasks for a budding Revit add-in developer experienced in ObjectARX or other CAD system programming is to forget her accumulated previous experience and open her mind for something completely new and different.

Learning something new and

letting go of something old

can prove very challenging indeed.

And very rewarding.

Good luck!


Comments

6 responses to “No Inheritance and No Strong Naming”

  1. I find the reasons Autodesk doesn’t digitally sign their API assemblies to be somewhat lame. I believe only the first 2 octets of a version number “count” when a .NET add-in loads a digitally signed assembly (only change the later digits, guys, or don’t change it at all because only one ever gets loaded at runtime, right?), and SO WHAT if you need to deploy it to the GAC to improve performance??? (That’s the real reason, as I read it…Autodesk’s complex installer can’t do gacutil -i???)
    In our case, we have reusable DLLs that depend on the Revit API DLLs, and those reusable DLLs are used in multiple add-ins (with separate installs to separate folders, conforming to the Autodesk Exchange Apps requirements). As the Revit API DLLs aren’t signed, we can’t sign our reusable DLLs.
    If an older add-in is run first, it loads our older reusable DLLs into memory and because they’re not signed those older ones that are already in memory will get used by the newer add-in, which when run may really depend on features in a newer version of the reusable DLL that shipped with it. Crashola. Or worse: quiet misbehaving.
    As neither “workaround” is suitable for us, the inability for us to easily sign our reusable DLLs that depend on the Revit API with Visual Studio can actually be quite problematic.

  2. Hmmm…upon further reflection I can see how the version number problem could be more complicated than I first thought. You could publish all versions to the GAC with every update release, but then any bug fixes may not get picked up automatically by add-ins that were originally built against older releases of the API DLLs. Obviously that would be desirable. Ugggh.

  3. Dear CoderBoy,
    Thank you very much for your input!
    Do you have access to the Autodesk beta Meridian forum?
    That is the origin of this discussion. It would be cool if you would like to explore this further there directly with members of the development team.
    Meanwhile, I have passed on your suggestions internally.
    Cheers, Jeremy.

  4. Adrian Hodos Avatar
    Adrian Hodos

    To put it frankly, the Revit API is an abomination. It should be taught as a model of how not to program at CS schools everywhere. I could spend hours talking about the coding horrors one has to make just to do something trivial (in other CAD programs) like applying a transform to a solid, or infer a relation between a bunch of objects. And let’s not forget about the “wise” decision of only allowing access from managed languages. This makes wonders for the performance of the code :) And don’t even mention the word multi-threaded, it is an unknown concept in the Revit world.

  5. Dear Adrian,
    Wow, cool.
    Thank you for your frank view :-)
    I very sincerely hope nobody is forcing you to work with the Revit API!
    I wish you the very best of luck on all your (hopefully) non-Revit related programming projects!
    Cheers, Jeremy.

  6. Arnošt Löbel Avatar
    Arnošt Löbel

    I hear you, Adrian, I really do. However, I would like you to (try) understand that there are always important reasons for the decisions the Revit R&D makes and serious considerations are always part of the decision process. For one, we believe that having a .NET API shell over Revit native internal provides most users with more stable platform, and that applies to Revit API developers as well as the end users that enjoy their add-ins. In my personal opinion, the .NET environment makes the API also more approachable to users that aren’t professional developers. At the same time, we do not restrict what advanced developers can do in their add-ins. If they wish to delegate some heavy calculations to other modules written in unmanaged languages, they quite easily may do that. In fact, Revit supplies some of its own add-ons that are written as multi-language, the cloud renderer being one example.
    As for multithreading, I actually do not believe our users think we ignore their wishes and requests out of spite. I know they understand that putting together a multithreaded environment is not trivial. It is not easy to write such applications from scratch. It is far more difficult to rewrite an old application to be completely multithreaded. And even with that difficulty being always part of the equation, some applications are just mode difficult to multithread than others. I am not saying impossible, but sometimes it is just too darn hard. Revit actually has many internal components that are threaded; however, trying to thread access to a database as complex and tiered as Revit’s data model is another task all together.
    I’d like to add one comment about the complexity (and, well, ugliness) of the Revit API. I think the same could be said about Revit itself when comparing it with other applications. Revit is indeed different. I do believe there are trivial tasks that would take minutes to do in AutoCAD while they can take an hour easily in Revit. On the other hand, however, I would not have to be pressed hard to come up with tasks which take minutest in Revit, but days in AutoCAD. I believe the same sentiment can be extended to other platforms and applications. There are users who swear to be much faster on their Macs then others can be on their Windows, and vice versa. And of course, the Unix hard-core crowd swears to be much more efficient with their command lines than all the GUI lovers combined. :-) But at the end of the day it is all about the right tool for the right tasks, isn’t it.
    Arnošt Löbel
    Sr. Principal Engineer
    Autodesk, Revit R&D

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading