Showing posts with label DotNet. Show all posts
Showing posts with label DotNet. Show all posts

Monday, August 18, 2008

.NET 3.5 SP1 - an obscure gift

JTBWorld pointed out a small but nice enhancement to the latest Service Pack for Microsoft .NET:

The fact that code executing from a network share now has the same permissions as code executing on your local hard drive.

(Begin Venting)
"What? it didn't before? Why?" - obviously you haven't had the pain of trying to make this work. Microsoft's concern was that code executing from a network share could be a virus, worm, etc - something undesirable. So they made it impossible. OK, so it wasn't impossible - they just made it aggravating. To make this work prior to now, you had to go into the world of CASPOL - Code Access Security POLicy, either through your control panel, your company security policies, or the CASPOL.exe command line tool. Fundamentally, you had to make guidelines for when to trust particular .NET assemblies (based on where they were installed, or a signed publisher cerificate, etc).

The joke is - that these restrictions were only for .NET applications. Any hacker who was using a non-.NET language had no such restrictions.

(End Venting)

Anyway - it's good news that it's a changed behavior. This should make it easier for average CAD Managers, IT managers and developers to support a centralized deployment methodology - whether for Revit, AutoCAD, etc.

(Note: Jimmy didn't even have it posted for a day before this caveat came up - you need to add an "acdbmgd.ini" file to force it to not optimize to .NET 3.5 SP1 work with AutoCAD at all).

Saturday, July 19, 2008

The minimum C# to learn to program Revit?

I received a good question the other day from someone who was interested in learning to program Revit. They had done some C programming years ago, and was somewhat overwhelmed by the size of the "Introduction to C#" kind of books (which do tend to be 3+ inches thick).

So I was trying to explain what the core concepts of C# (or any .NET language, for that matter) that they would need in order to get to the point where they would be "dangerous", as they say.

Here are my thoughts:

Object-Oriented Programming (OOP)
Everything in .NET (as well as everything in the Revit API) is built around objects. So you must understand the fundamentals of how to make and use objects.

  • Class definitions
  • Creating new objects
  • Fields and Properties and Methods
  • Object scope/lifecycle
  • The concept of NULL;
  • User Interface (any UI that you do revolves around OOP)

Basic language features
I originally didn't address this... you'll obviously need to learn the basic language features of whatever language you choose. Declarations, IF statements, dealing with Enumerated types, etc...

Enumerators, For loops and Foreach loops
Much of the Revit API revolves around these concepts for looking up elements or other information. Enumerators (or Iterators) is probably the least intuitive of the bunch.

Code Example:

// To go through all of the elements in the model, one way is to do the following:

ElementIterator ei = commandData.Application.ActiveDocument.Elements;

while (ei.MoveNext())
{
Element e = ei.Current as Element;

// now you do something with Element "e".

}

Arrays/Lists

Maybe it's just me, but almost every Revit application I'm involved with makes significant use of Arrays/Lists - so you may as well get comfortable with them. Personally, I'm a fan of what are called "Generic" Lists - which are lists of a specific type of object.

Code Example:

// if we had to go through all the elements, and find the elements that were "Pinned"

// Make our list object
List pinnedElements = new List();

// go through all the elements (NOTE: this way is far slower than some other alternatives - but reasonable for beginners)
ElementIterator ei = commandData.Application.ActiveDocument.Elements;

while (ei.MoveNext())
{
Element e = ei.Current as Element;

if (e.Pinned) pinnedElements.Add( e ); // if it is pinned, add it to the list
}

// now presumably we do something with all those pinned Elements we found...

Object Casting

I'm not sure if they still call it this in the books - but that's how I learned it. This would be used, for example if you had an "Element" from Revit, but you wanted to determine if it was a "Wall" so that you could get the wall-specific information from it.

There are a few mechanisms which support this kind of goal:

Code Example:

// Let's assume that I have "Element e" from one of our routines above, and we want to determine if it's a Wall, so that we can get the Wall width.

//option 1: direct casting

Wall myWall = (Wall)e; // cast "e" into a Wall.

// The down side of this approach? It throws an exception if "e" is not a wall. Which you could catch, but that's time consuming.

// option 2: testing first using the is

if (e is Wall) myWall = (Wall)e;

// this is OK as an approach... better than option 1 at least.

// option 3: using the AS keyword

Wall myWall = e as Wall;

// the benefit here? it casts it if it is the right type. If it's not? then myWall is NULL (which you'll need to test for).

All the methods described above have pros and cons in terms of writing the code and the performance of the application... So they're not meant to be instructive on either, so much as show you some possibilities.

I hope this will be useful to someone...

-Matt