FilesDesk

2012

This started out as a side project between a couple of us at work to sharpen our C#/XML skills and generally do something challenging. A C#.NET Application + Service that enables browsing files on disk by Tag (as opposed to Path). Typical usage:

  • A Tag Cloud for your hard disk
  • Add/remove tag(s) to selected file(s)
  • List & Filter files by tag(s)
  • Monitor specified folders (ex: My Documents) for new/deleted/renamed files
  • Portable XML Database

Useful for Researchers, Writers and Obsessive-Compulsive File Hoarders.

Advertisements

Software Design Simplified

I was remotely reviewing a new team member’s code:

It wasn’t that bad, but I wrote him a document suggesting some general design principles. I’m repeating some of them here, because they seemed to be the sort of thing that I would like to refer to often.

  1. For the typical application, start with the 3 basic layers: Front-end (GUI), Back-end (Database) and Business Logic. Give them their own classes within separate projects in the solution.
  • Ensure there are no cyclic dependencies
  1. Establish well-defined interfaces between the layers.
  • Internal implementation within a layer should be modifiable, with minimal (ideally zero) impact on other layers
  • Control should flow cleanly between layers, not back & forth
  1. Don’t duplicate code (or data structures) amongst layers (DRY Principle)

  2. At the highest level, each class should map to a real-world object that you intend to manipulate.

  • Then start breaking down the functionalities and add more classes at the lower levels
  • Try as much as possible to adhere to Object Oriented Principles, and at the very least to the one-class-one-responsibility principle (SOLID) (Annotation: I know it sounds obvious, but you’d be surprised what passes for “object oriented programming” these days)
  1. Don’t try to cover all the possible use cases up-front, instead aim for a design that has a solid foundation, on top which features can be added iteratively (YAGNI Principle)

  2. The earlier you put in place a flexible logging mechanism (whether your own or reused), the happier you’ll be. No application is too small to benefit from logs. Besides debug info, they can also serve a source of useful information that the user need not be burdened with under normal circumstances.

  3. Prioritization: Normally I would proceed in the order:

  • Functionality, Reliability
  • Usability
  • Robustness, Security
  • Efficiency
  • Maintainability, Portability
  1. Tools:
  • Mindmaps for capturing Requirements & Design (Reference)
  • Dia for flowcharts  (Annotation: Yeah, I’m old skool)
  • StarUML for UML Diagrams

C# Reflection and Dynamic Method Invocation

Gopalan Suresh Raj has written up a detailed article on the subject. I used it for dynamically creating objects of a class whose name was read in as a String.

More C#.NET Resources

MeshPlex, a community-driven, wiki-based tutorial database, has a fairly good collection of C# knowledge here. It is divided into “Basics” and “Advanced”, so you are sure to find something that meets your requirement.

Check out a clean and very well-explained set of C#.NET articles from Jon Skeet here.

ExtremeExperts.com hosts some interesting technical articles and HOWTOs for Microsoft .NET based technologies.

And these, ripped from the Visual Studio product datasheet:

XML To TreeView

Another nifty one at MSDN (no wait, it’s Microsoft Support!) about populating a TreeView control with XML data.

C#.NET PropertyGrid Resources

Some stuff on the one-class-fits-all C# PropertyGrid:

C#.NET Form Tricks

An interesting article titled Windows Forms Tricks You May Have Missed at CodeGuru.com

Trapping the Close “X” Button in a Form

Want to hide a form instead of closing it? Here’s a quick solution.

Resizing an MDI Child Form to Fit its Parent

Here’s a useful snippet for resizing an MDI child form to fit its parent, minus the title bar, menu bar, status bar and so on:

foreach (Control ctrl in MdiParent.Controls)
{
    if (ctrl is MdiClient)
    {
        Width = ctrl.ClientSize.Width;
        Height = ctrl.ClientSize.Height;
        break;
    }
}