[Gregor.NET]

The Gregor.NET Application Framework

Sunday, August 03, 2003

Gregor.NET is a collection of .NET assemblies. The focus is on Windows application programming based on class libraries (altough there are a few actual programs as well). These projects are written in VB.NET, C#, and Managed C++.

Gregor.NET picks up discontinued VB6 projects, such as VBInet and WebEdit, while reorganizing much of the functionality found in VB6Core into several smaller class libraries. COM components written in C++ have also been brought into the .NET world (for example, the WinShell library).

So far, pages on class libraries are developer-oriented, and briefly introduce each namespace. Pages on applications (like WebEdit.NET) give a user-oriented overview of the programs.

On the downloads page, there are a few related items, such as utilities or AddIns for the programs found here, that aren't documented.

What Gregor.NET is (not) about

These projects are my personal babies, and this is perhaps the best I can say. I want to have some fun with .NET, find out and share what can be done with it, but also use the apps for my own purposes. WebEdit.NET, in particular, is a key player in a closed cycle of activities: coding an editor to author my homepage with, on which I inform about that editor; it's a self-referential system.

Although I try to produce good components and apps, which might even be marketable some day, there are some important areas where Gregor.NET's quality is far from what you would expect from any commercial product: this applies chiefly to internationalization and localization, documentation, performance, and backwards compatibility (while compatibility matters for extensible, scriptable apps like WebEdit, I don't feel [nor want to feel] any market forces in this respect; although I typically don't throw things arround for no reason).

So, use things as you see fit, and have some fun. Or create your own web site, and put your own projects up. I hope this doesn't sound rude - I'm just trying to ignore web traffic, popularity, and money issues. Note that while I give my stuff away both freely and gratis, I reject both the "open source" and the "free software" labels, because these are complex topics, and I don't have a strong opinion either way.

Project overview

Namespace organization

Every assembly has a top namespace called "Gregor". Hopefully, there aren't that many other Gregors arround that write .NET assemblies and choose their first name for the top level namespace.

Every project then has, at the second level, a namespace named after the project. For example, all full naming paths in UI core start with "Gregor.UICore".

Larger projects further subdivide into third-level namespaces, like "Gregor.UICore.Docking" or "Gregor.Core.Collections". I never go any deeper than that (kinda VB-like, if you know what I mean).

Project builds and dependencies

The projects should be built in the following order (dependencies are listed in parens; you'll find everything you need on the downloads page):

I recommend keeping binaries in a common repository (directory), and using project references. By default, each assembly gets built into a sub directory named "Assemblies\Bin" parallel to the solution directories.

Coding conventions

Types and files

The rules is: one type, one file. Exception are event handler delegate types, which live with their corresponding event argument classes. Short classes sometimes mate in a single file as well.

Regioning

Within a class, there are several regions. The particular choices (like "Static stuff" or "Properties") serve one purpose: making my code organization principles applicable to any language, development platform, or project, by using strictly general technical categories, not a functional or ad-hoc order that might appear to be mandated by a class's particular purpose.

They say that data (i.e., fields) is to be separated from methods, and I agree. However, I think that the distinction between static and instance members is even more important (because of cardinality), so all static stuff goes into the alike-named region (with data and functions separated).

Naming

I'm slowly relaxing the Hungarian naming convention, but I'm not ready to give up just yet.

I use prefixes on type names which denote the type's general kind ("C" = general class, "I" = interface, "T" = structure). Some prefixes on class names denote the general category of the class ("N" = collection class, "F" = form class, "X" = control class). Enums and delegates do not have prefixes. As for enums, I make an honest effort to use plural names only for enums that deserve the System.Flags attribute. Delegate types are recognizable by the "Handler" or "Callback" postfixes.

Another issue are modules, which aren't types in my view: in languages that are honest about their procedural roots, modules used to be prefixed an "M", and otherwise pretended to be a class ("C"); but the new rule is to skip prefixes for modules altogether.

Variables are camel-cased, and some have a prefix (a boolean always starts with an "f", and a string with an "s"; besides that, integers are prepended a prefix if appropriate); the prefixes are governed by semantics, that's why they only appear for variables of certain types. Of greater consequence is the scope/cardinality prefix (if any naming convention really matters, I think it is this one). Scope and cardinality are about logic, about state, so there are hells of difference between static ("s_"), instance ("m_"), and local (no scope prefix) variables. On the other hand, distinguishing method arguments from other locals does not warrant a naming convention in my view.

Otherwise, I stick with Pascal casing (projects, namespaces, type members), and all-caps for constants.

Custom Attributes

I use the attribute classes defined in Gregor.Core for documentary purposes. Examples are the Description attribute, or the Module attribute, both of which are recognized by the assembly browser offered by Gregor.AppCore.

Miscellaneous

I always qualify method calls with either the type name or the "this" pointer. For the latter case, it's because I feel that when I call a routine, I should provide all the arguments needed. In any case, code readability improves, and the nice about C# is that the compiler will make sure that what looks like an instance (static) call will also be an instance (static) call.

Other notes

Some screen shots are of date, mainly because the UICore component keeps evolving. The better looking pictures are the most recent pictures ones, of course.

More Materials

Downloads

You can download all sources and binaries off my Download Center.

Documentation

The most useful documentation is in source code comments, test projects, and articles on this site. There are generated API docs as well, although they aren't very detailed: look here.

Resources

This page lists additional resources for Gregor.NET libraries and applications.