New Job

by Damon 19. January 2005 06:00
Well, I suppose it is now official. I have resigned my position at Centare Group and accepted another position.

My time at Centare was pretty good. It was there that I eventually started to grow into the leadership/senior roles I've always wanted. It was during my time there that my daughter was born, and a lot of other huge life events happened. It was at Centare that I wore the title "Microsoft Business Group Manager" for a while and did a great deal of work with Brian Tinkler trying to get Centare up and running and known as a solid Microsoft partner. (After many years of good rep as a solid IBM partner) Either because of, or inspite of, those early efforts Centare went from zero to several .NET people.

My new gig will be Principal Architect at SafeNet Consulting Services. They are also looking to grow their Microsoft practice and the opportunity seems like the right thing at the right time.
Not only will I get a fancy title on my business cards, but SafeNet's model will offer me a little more freedom where my own business endeavors are concerned. Hopefully, this opportunity combined with some big personal events (like building a house) will make this a fantastic year for me and my family.

One of the biggest take aways from my leadership reading this year is the notion of the Abundance Mentality. In keeping to this principle, I wish Centare all the success in the world, and look forward to chasing after my own.

Tags:

Compact framework

by Damon 15. January 2005 06:00
While surfing the dotnet public newsgroups for solutions to other issues, I came across two questions over and over again related to the Compact Framework. Perhaps if I post solutions here Google will help people find the answer in plain English and C#.
  1. How can I be sure to run only 1 instance of my application on the compact framework?
  2. Dotfuscator Community Edition doesn't work on the compact framework!

Like most things that are missing from the CF, the easiest solution to #1 involves using PInvoke to access functionality in the Win32API:

                   [DllImport("coredll.dll")]

                   private static extern int  FindWindow(string lpClassName, string lpWindowName);

 

                   [DllImport("coredll.dll")]

                   private static extern bool SetForegroundWindow(int hwnd);

            int hWnd = FindWindow( null,  "Main Window title");    // you can also add your app class name

            if (hWnd != 0)    

            {     // bring to the front the other instance

                SetForegroundWindow(hWnd);

                                      return;

            } // else run new instance

As I said, I also saw tons of posts related to Dotfuscator not running with Compact Framework Assemblies even though the vendor swears it does. The solution I found is twofold. The problem with the version distributed with Visual Studio 2003 usually manifests itself with something like "Unable to load some of the types"

  1. Register your copy of Dotfuscator and download the update for the community edition from their site.
  2. Even with some things in the GAC or plainly referenced by hard paths in your solution, Dotfuscator had trouble finding some of my assemblies. Changing some of my references (such as the System.Data.SqlServerCe reference) to "copylocal" allowed dotfuscator to run successfully on a very large compact framework application.

Happy coding.

Tags:

User Group Presentation

by Damon 12. January 2005 06:00
I did my cryptography presentation at the Wisconsin .NET user's group last night. It seems to have went well. Many thanks to WINETA for having me, and for the kind words and excellent questions from those who attended.
If they let me come back, Designer Support is the next topic I'd like to tackle. Designer support is probably one of the coolest features in .NET that is seldom used or talked about and yet is very powerful if you take the time to do it.

With the UG presentation out of the way, I can return to pondering some of my other tasks, such as the ASP.NET issue I posted before.

Tags:

Tired of Javascript

by Damon 21. December 2004 06:00

I write a lot of web applications, but I don't like JavaScript. Too many applications made today are forced to be browser applications when the functionality clearly indicates a desktop solution.

There, I said it. I never did much client-server programming so I can't really be accused of holding on to something who's time has come. There are certainly many benefits to web applications too, not the least of which is ease of deployment to the end user. However, after doing several applications that overused javascript in the worst ways (Like implementing a QuickSort that could sort table rows using the DHTML object model) I became very tired of Javascript, with its many idiosyncrisies and fragile nature. I have been accused lately of going too far down this anti-script path. In ASP.NET, its just too easy to set items to auto post back and create the desired effects from within the safe and familiar environment of my favored, garbage collected, strongly typed and compiled language of choice.

To be fair, I view the fact Microsoft has put a great deal of effort into making it easy to deploy WinForms applications via the AppUpdater block and features in VS.NET 2005 as support for my opinions. Web Services + Thick Client + Easy Deployment = Best of many worlds. Even Sun had it figured out several years ago when the came up with Java WebStart: why not run a desktop app via a shortcut to a web site that checks for updated versions of the code it needs to run? Of course, writing desktop apps in Java is less fun than covering yourself with papercuts and jumping into a pool filled with ice-cold lemon juice, so JWS does them little good.

My point in all of this rant was that .NET is wonderfully extensible in many different ways. It was suggested to me that server-side code could be written to generate some basic and common client side Javascript actions, such as making it so that a radio button list could hide or show an ASP:Panel depending on its selection, without postbacks. Seems simple enough, but if designed properly it could be the first step towards bigger and better things.

Without doing any code experimentation yet, I can think of 3 ways I might set out to do this:

Ineritance

Inherit from controls already in .NET to add the functionality desired. For example, create a custom RadioButtonList that is smart enough to generate client side events to perform some action. The problem with this is that I want to leave inheritance as a last result. I may purchase some 3rd party component that I wish to add this functionality to, meaning extending the base controls may not be an option.

Builder

Some type of builder pattern may be appropriate, where the attributes needed to provide the desired run-time functionality are added via logic encapsulated in Builder classes that operate on otherwise vanilla ASP.NET web controls. The downside of this solution is that it seems like it could be a little more dran-n-drop than adding a few lines to your code behinds manually.

Custom Control Library

This idea is intriguing, although probably slightly overengineering a simple problem. We could probably create a library that would allow us to write ASP code such as the following:

<library:ToggleVisibleRunat="server"  ShowValue="Yes" HideValue="No"  Target="loginPanel" Event="IndexChanged" ID="Clientaction1" NAME="Clientaction1">

          <asp:RadioButtonList Runat="server" ID="showLogin" AutoPostBack="False">

                   <asp:ListItem>Yes</asp:ListItem>

                   <asp:ListItem>No</asp:ListItem>

          </asp:RadioButtonList>

</library:ToggleVisible>

<asp:Panel Runat="server" ID="loginPanel">

          ... other stuff here ...

</asp:Panel>

With this type of metaphor, we could also allow dran-n-drop coding, and allow the values such as "ShowVaule" and "Target" to be configured via the Properties Grid and .NET's most excellent design-time support. I will think about this, and come back after some experimentation.

Tags:

New Blog is almost done

by Damon 9. December 2004 06:00
I wrote some new blog software.
I wanted a more functional dynamic site. It seems to me that 99% of people inclined to keep a software blog are using a pre-packaged solution like DasBlog. A coworker warned me that blog software was non-trivial and could quickly get out of hand. I took this as any self respecting C# developer with an average sized ego would: a clear reason to do it anyway. After stealing a design idea from Open Source Web Design here I am.I'm sure I haven't implemented all the features of something like DasBlog but then again a cute calendar and HTTP_REFERRER tracking aren't big priorities of mine. I have a couple of features I will implement when I get the time though, such as the comments. I'll probably make a couple of posts later about the blog itself, likely the parts that are over-engineered just to try something.

Tags:

Speaking

by Damon 9. December 2004 06:00

What seems like ages ago I spoke at WINETA about Agile Development in the .NET world. When Larry Clarkin made a point of saying that two-time WINETA speakers were a rare-breed indeed I resolved to join that small circle. A while back I had asked the wineta president if I could speak about digital cryptography.

Digital cryptography is near and dear to my heart because its one of the things that got me into .NET. I was writing some client apps that needed to exchange RSA and RC2 key data with some XML web services written in C#. When helping someone debug an issue I sometimes get to the point where I say "Let me drive", meaning I'd like to man the keybaord. I had not gotten down and dirty with an MSFT tool since writing a little OpenGL in Visual C++ 6. Ten minutes with C# and Visual Studio was all it took for me to know this was a better way to go.

At any rate, after this project I did a decent amount of work researching cryptography and learning a little more about the under the hood stuff than you can learn just by looking at API documentation. I now have some experience with algorithms and some of the subtleties of crypto (who knew character encoding would be the #1 things that trip people up?) that comes in handy from time to time, even very recently at work.

At any rate, I intend to cover the the "basics" of a very complex subject:

  • Brief history of crypto
  • Bit twiddling examples
  • Overview of algorithms
  • Overview of algorithm styles (ECB vs CBC vs CBF)
  • ... all with plent of .net code examples
  • WEP key cracker and examples of some crypto attacks, if I have time
Come and see me, if you are so inclined, January 11th, the details are on the WINETA site above.

Tags:

Sorting Custom Types in code

by Damon 3. December 2004 06:00

Updated (Solution posted)

If you are writing a .NET application you may be tempted to use DataSets to represent relational data in your application. There are any number of good reasons not to use DataSets and even more reasons you may encounter (especially when integrating with systems you cannot control) where DataSets are not an option. An excellent alternative is a Custom Type.
When I implement Custom Types in a system to represent my data I tend to follow a couple of guidlines:
  • Use Properties instead of public fields. If I want to bind to say, a list control of some type, the Reflection that goes on at runtime will often treat properties different from public fields.
  • Keep my types dumb, the business logic operations dealing with these types is contained elsewhere, like business logic classes or validation controls
  • Follow a naming convention like CamelCase
  • Pass groups of Types around in a Collection class like ArrayList (this will be nicer with template types in Whidbey)
  • Avoid frameworks that force Type inheritence where possible

A simple example, then, may be:

          public class BlogEntry

          {

                   private String text;

                   public BlogEntry()

                   {                          

                   }

                   public string Text

                   {

                             get{return text;}

                             set{text = value;}

                   }

          }

And, yes, my Property doesn't do much, but its there mostly for run-time binding.

Using DataView.Sort its very easy to use code already in the runtime to sort DataRows. With Custom Types however there is no readily apparent built in solution. Dig slightly beneath the surface and you will find the IComparer interface and the ArrayList.Sort(IComparer). This, then, is one solution, but how can you implement this model without very large if/then statements that are specific to a Type? I would like to:

  1. Be able to sort an ArrayList of Types based on any primitive property they may have
  2. Write code that is not specific to one type
  3. Support case-insensitive String comparison and reverse-sorting
  4. Make the implementation shorter than a long if-then statement
  5. Execute this with only a line or two of code, just like when using DataView

Solution: Reflection and Delegates

The solution is easy using two excellent .NET features: Delegates and Reflection. Delegates will allow me to use different comparison functions dependent upon the Type of the field I want to compare; Reflection makes it easy to identify metadata about classes at runtime. For now supporting int, String, Date, and double types will suffice for most needs. Here is my Type Comparer.

using System;

using System.Collections;

using System.Reflection;

 

namespace damonpaynedotcom.Types

{

          /// <summary>

          /// Make it easy to Sort Custom Types

          /// </summary>

          public class TypeComparer : IComparer

          {

                   private delegate int DoCompare(object x, object y);

                   private DoCompare _compareMethod;

                   private PropertyInfo _propInfo;

        private Hashtable _methods;

                   private bool _caseSensitive;

                   private string _sortProperty;

                                     

                   public TypeComparer(string propertyName, Type objectType)

                   {

                             _caseSensitive = true;

                             _sortProperty = propertyName;

                             _methods = BuildSortMethods();

                             _propInfo = objectType.GetProperty(_sortProperty);

                             if (null == _propInfo)

                             {

                                      throw new ArgumentException(string.Format("Type {0} does not have a Property '{1}'", new Object[] {objectType.ToString(), propertyName}));

                             }

                             _compareMethod = (DoCompare)_methods[_propInfo.PropertyType];

                             if (null == _compareMethod)

                             {

                                      throw new ArgumentException( string.Format("Type not supported: {0}", _propInfo.PropertyType) );

                             }

                   }

 

                   protected Hashtable BuildSortMethods()

                   {

                             Hashtable ht = new Hashtable();

                             ht.Add(typeof(int), new DoCompare(CompareInt));

                             ht.Add(typeof(double), new DoCompare(CompareDouble));

                             ht.Add(typeof(string), new DoCompare(CompareString));

                             ht.Add(typeof(DateTime), new DoCompare(CompareDate));

                             return ht;

                   }

 

                   public bool CaseSensitive

                   {

                             get{return _caseSensitive;}

                             set{_caseSensitive = value;}

                   }

 

                   protected int CompareInt(object x, object y)

                   {

                             int xInt = (int)x;

                             int yInt = (int)y;

                             return xInt.CompareTo(yInt);

                   }

 

                   protected int CompareDouble(object x, object y)

                   {

                             double xDouble = (double)x;

                             double yDouble = (double)y;

                             return xDouble.CompareTo(yDouble);

                   }

 

                   protected int CompareDate(object x, object y)

                   {

                             DateTime xDate = (DateTime)x;

                             DateTime yDate = (DateTime)y;

                             return xDate.CompareTo(yDate);

                   }

 

                   protected int CompareString(object x, object y)

                   {

                             string xString = (string)x;

                             string yString = (string)y;

                             if (!CaseSensitive)

                             {

                                      xString = xString.ToUpper();

                                      yString = yString.ToUpper();

                             }

                             return xString.CompareTo(yString);

                   }

 

                   #region IComparer Members

 

                   public int Compare(object x, object y)

                   {

                             object xVal = _propInfo.GetValue(x, null);

                             object yVal = _propInfo.GetValue(y, null);

                             return _compareMethod(xVal, yVal);

                   }

 

                   #endregion

          }

}

If the need ever arises, I may experiment with algorithms for multiple-level sort or sorting based on non-primative types. I also need to work a little bid on the code-formatting styles!

Tags:

I am not famous

by Damon 3. December 2004 06:00

eXtreme Programming book actually printed

I googled my name to see if it had found DamonPayne.com yet and what do I find but a book I worked on so long ago it seems like another lifetime. Behold, a truly ancient book written concerning that "other" single inheritance, garbage-collected, managed programming platform.
I have to admit I actually wasn't happy to see this come out. Its a long story, but in a nutshell I wasn't happy about how the editor handled this project. This incident caused me to stop and ask myself if I should get published in .NET since I vastly prefer it to the "other thing". Right now and for the forseeable future I'm too busy implementing things to write about things, except perhaps for this blog.

Tags:

About the author

Damon Payne is a Microsoft MVP specializing in Smart Client solution architecture. 

INETA Community Speakers Program

Month List

Page List

flickr photostream