Sign In

Navigation

On This Page

DeflateStream and zlib
LINQ: Refactoring Inline Instantiation
Twin Cities Code Camp
InteliShade.Net: HLSL Syntax Highlighting and Intellisense
C# Event Declarations
Got a new PC
Unit Testing for the first time
Project Documenting under a deadline
Updates
The blog hath arrived

Archive

<September 2008>
SunMonTueWedThuFriSat
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

Categories

Blogroll

Contact

Send mail to the author(s) Email Me
MCPD
MCTS

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way


Copyright ©  2012
 Creative Commons License
This work by Jeff Klawiter is, unless explicitly stated in the article,  available under the Creative Commons Attribution 3.0 United States License.

Pick a theme:
# Friday, September 19, 2008
by Jeff Klawiter - Friday, September 19, 2008 8:42:40 AM (Central Standard Time, UTC-06:00)
The company I work for, Sierra Bravo Corp, got its start connecting legacy PICK systems to the modern world. They accomplished this via a proprietary client-server protocol we internally call db_server (Official name is SierraDBC or BravoConnecter). Sure there are other PICK connection technologies out there none of them support multiple PICK systems and OS Platforms. Currently we support : D3, Universe, UniData, JBase, MvBase and others I don't remember right now.

I maintain the .NET client library. It was originally a port of the Java library which was a port of the COM library. It's come quite a long way since then. Recently we've found the need for compression to be added for some of our client. One in particular has many employees out in the field connecting via AirCards where bandwidth availability can be a problem. On top of that the application needs to retrieve quite a bit of real time data from the home office. Retrieving 2mb of client history is not unheard of.

After the server developer added compression to the result stream I started working on the client end. I figured it should be a snap. If we have compression turned on, just pass in a DeflateStream (fed by the NetworkStream of the TcpClient connection) to the StreamReader we already use to retrieve the results.

StreamReader ResultReader;
if (IsConnectionTypeSet(ConnectionOptionTypes.EnableCompression))
{
    DeflateStream dfs = new DeflateStream(ns,CompressionMode.Decompress);
    ResultReader = new StreamReader(dfs, Encoding.ASCII, false);
}
else
{
    ResultReader = new StreamReader(ns, Encoding.ASCII, false);
}
One would think that's all that it would take, right?

I was sadly mistaken. I would receive an exception (System.IO.InvalidDataException:"Block length does not match with its complement.") every time I would try to read from the stream.

The issue lies in the use of zlib for the compressed stream. zlib and DEFLATE use the same algorithm for compression. The difference is zlib sends two bytes of header data. So all the answers I found were to pop off the first two bytes of the stream.
StreamReader ResultReader;
if (IsConnectionTypeSet(ConnectionOptionTypes.EnableCompression))
{
    DeflateStream dfs = new DeflateStream(ns,CompressionMode.Decompress);
    ResultReader = new StreamReader(dfs, Encoding.ASCII, false);
    ns.ReadByte();
    ns.ReadByte();
}
else
{
    ResultReader = new StreamReader(ns, Encoding.ASCII, false);
}
 This worked just fine but I was annoyed about how ugly it looked. I needed to move that ugliness out of there. So I wrote a ZlibStream class to do this for me. I made it for only Decompressing streams since I didn't have the budget to go and actually implement the zlib headers.

[ZlibStream.cs]
    /// <summary>
    /// Supports decompressing a DeflateStream created by the zlib library
    /// </summary>
    class ZlibStream : DeflateStream
    {
        #region Fields

        private bool HasRead = false;

        #endregion

        #region Constructors
        /// <summary>
        /// Initiates ZlibStream in Decompress mode
        /// </summary>
        /// <param name="stream">One of the System.IO.Compression.CompressionMode values that indicates the action to take</param>
        public ZlibStream(Stream stream)
            : base(stream, CompressionMode.Decompress)
        {

        }
        /// <summary>
        /// Initiates ZlibStream in Decompress mode
        /// </summary>
        /// <param name="stream">One of the System.IO.Compression.CompressionMode values that indicates the action to take</param>
        /// <param name="leaveOpen">true to leave the stream open; otherwise, false.</param>
        public ZlibStream(Stream stream, bool leaveOpen)
            : base(stream, CompressionMode.Decompress, leaveOpen)
        {

        }
        #endregion

        #region Public Methods

        public override int Read(byte[] array, int offset, int count)
        {
            if (HasRead == false)
            {
                this.BaseStream.ReadByte();
                this.BaseStream.ReadByte();
                this.HasRead = true;
            }
            return base.Read(array, offset, count);
        }

        #endregion

    }
As you can see it is very simple. Since all the StreamReader does is call the Read method I just needed to remove those bytes during the first pass.  This class is extremely simple and limited in its functionality. Doing Asynchronous reads with BeginRead will not work. I checked via reflector and it does not use the DeflateStream.Read method. It handles the BaseStream's Read methods on its own.

The one thing I may need to expand is doing the popping of the two bytes. Currently it's not checking to see if the stream has any bytes to read. So far in testing this hasn't been a problem. I'm going to try and see if I can create a situation where the bytes are not available initially. I have a suspicion that the ReadByte() waits for a Byte to be available and errors out on the Timeout value

So my result is as elegant as can be
StreamReader ResultReader;
if (IsConnectionTypeSet(ConnectionOptionTypes.EnableCompression))
{
    ZlibStream dfs = new ZlibStream(ns);
    ResultReader = new StreamReader(dfs, Encoding.ASCII, false);
}
else
{
    ResultReader = new StreamReader(ns, Encoding.ASCII, false);
}

Comments [2] #      C#  |  kick it on DotNetKicks.com Shout it
# Saturday, August 23, 2008
by Jeff Klawiter - Saturday, August 23, 2008 2:39:02 PM (Central Standard Time, UTC-06:00)

Over the summer I was able to run my first large project in .NET 3.5. I had a chance to put to use all the new features and learned quite a bit on the way. I've blogged a bit about this project before. The project contained 2 data backends a local SQL database and a 3rd-party ASMX service. I took the approach of having a business object library that contain only class definitions that I had full control over. I split out the backends to their own libraries with a main Datalayer library that handled the communication with the two underneath it.

Initially I started coding the two bottom layers to do the object instantiation inline in the LINQ queries. As the layers grew I began to refactor much of the instantiation to methods that mapped the layer objects to the business objects.

Converting an inline expression like this

var result = from id in dc.OrderDetails
             where id.OrderID == OrderId
             select new DataObjects.OrderItem()
             {
                 PartID = id.PartID,
                 Price = id.Price,
                 Quantity = id.Quantity
             };

To this

var result = from id in dc.OrderDetails
             where id.OrderID == OrderId
             select MapOrderDetailToOrderItem(id);

Using the LINQ to SQL Classes was a perfect fit. They are by far much easier to use as an ORM than SQL Datasets and DataAdapters are. When retrieving lists such as items on an order the relationship propertis on the SQL objects made it extremely easy to have clean data access.

After completing the project I started thinking about what the performance impact of the refactoring had on the data access. So I decided to run some tests. Initially I thought that the inline instantiation would probably be faster since it was constructing the object in the expression instead of getting the SQL objects and then passing it to a function.

I wrote a quick program to do some performance testing on both implementations. I set up examples using a common real world call. Retrieving an order from a database with the line items on the order Below you can see the inline call and the refactored call.

[Tests.cs]
    static class Tests
    {
        public static void RunInlineInitialization()
        {
            using (SqlOrdersDataContext dc = new SqlOrdersDataContext())
            {
                var result = from o in dc.OrderHeaders
                             select new DataObjects.Order()
                             {
                                 CustomerID = o.CustomerID,
                                 OrderDate = o.OrderDate,
                                 OrderID = o.OrderID,
                                 OrderTotal = o.Total,
                                 ShippingAddress1 = o.ShippingAddress1,
                                 ShippingAddress2 = o.ShippingAddress2,
                                 ShippingCity = o.ShippingCity,
                                 ShippingDate = o.ShippingDate,
                                 ShippingMethod = o.ShippingMethod,
                                 ShippingState = o.ShippingState,
                                 ShippingTotal = o.ShippingTotal,
                                 ShippingZip = o.ShippingZip,
                                 SubTotal = o.SubTotal,
                                 TaxTotal = o.TaxTotal,
                                 TrackingNumber = o.TrackingNumber,
                                 Details = o.OrderDetails.Select(od => new DataObjects.OrderItem()
                                 {
                                     PartID = od.PartID,
                                     Price = od.Price,
                                     Quantity = od.Quantity
                                 }).ToList()
                             };
                DataObjects.Order order = result.FirstOrDefault();
            }
        }
        public static void RunRefactoredInitialization()
        {
            using (SqlOrdersDataContext dc = new SqlOrdersDataContext())
            {
                var result = from o in dc.OrderHeaders
                             select MapOrderHeaderToDataObjectOrder(o);
                DataObjects.Order order = result.FirstOrDefault();
            }
        }

        private static LinqTest.DataObjects.Order MapOrderHeaderToDataObjectOrder(OrderHeader o)
        {
            return new DataObjects.Order()
            {
                CustomerID = o.CustomerID,
                OrderDate = o.OrderDate,
                OrderID = o.OrderID,
                OrderTotal = o.Total,
                ShippingAddress1 = o.ShippingAddress1,
                ShippingAddress2 = o.ShippingAddress2,
                ShippingCity = o.ShippingCity,
                ShippingDate = o.ShippingDate,
                ShippingMethod = o.ShippingMethod,
                ShippingState = o.ShippingState,
                ShippingTotal = o.ShippingTotal,
                ShippingZip = o.ShippingZip,
                SubTotal = o.SubTotal,
                TaxTotal = o.TaxTotal,
                TrackingNumber = o.TrackingNumber,
                Details = MapOrderDetailToDataObjectOrderItem(o)
            };
        }

        private static List<LinqTest.DataObjects.OrderItem> MapOrderDetailToDataObjectOrderItem(OrderHeader o)
        {
            return o.OrderDetails.Select(od => new DataObjects.OrderItem()
            {
                PartID = od.PartID,
                Price = od.Price,
                Quantity = od.Quantity
            }).ToList();
        }
    }

As you can see both public methods do the same thing. The second test was refactored easily using the Refactor-Extract Method menu item in Visual Studio. I load the orders from the database, take the SQL OrderHeader object and map it to the business object. The Details property on the Order object is simply a generic list of OrderItems. To retrieve them I do a quick lambda expression to query the OrderDetails relationship property. 

For some the refactoring goes without saying. Modularizing code like this makes it more maintainable and reusable. This concept can be foreign to some procedural programmers. With Visual Studio and addins like Resharper refactoring becomes so easy it's almost an afterthought to do it. For anyone that still doesn't see the benefit with refactoring, I hope this article will help you.

The testing program is pretty simple, pass in the amount of iterations and a boolean to turn pre-JITing on or off.

[Program.cs - (some code removed for brevity)]
        static System.Diagnostics.Stopwatch stp = new System.Diagnostics.Stopwatch();
        static int Runs = 10;
        static bool PreJitRoutines = false;
        
        static void Main(string[] args)
        {
            ProcessCommandLineArguments(args);

            //Lets get JIT over all the methods in question
            if (PreJitRoutines)
            {
                PreJitTestRoutines();
            }
            //Display Current Selected Options
            Console.WriteLine("Number of Runs: {0}", Runs);
            Console.WriteLine("Pre JIT Enabled: {0}", PreJitRoutines);
            
            //Run and Measure Inline Test
            stp.Start();
            for (int i = 0; i <= Runs; i++)
            {
                Tests.RunInlineInitialization();
            }
            stp.Stop();
            //Display Test Results
            Console.WriteLine("Inline Initialization Test: {0} , Average: {1}", stp.Elapsed, new TimeSpan(stp.ElapsedTicks/Runs));
           
            //Save Result for later calculations
            TimeSpan FirstRun = stp.Elapsed;
            
            //Reset StopWatch
            stp.Reset();

            //Run and Measure Refactored Test
            stp.Start();
            for (int i = 0; i <= Runs; i++)
            {
                Tests.RunRefactoredInitialization();
            }
            stp.Stop();
            //Display Refactored test results
            Console.WriteLine("Refactored Initialization Test: {0} , Average: {1}", stp.Elapsed, new TimeSpan(stp.ElapsedTicks / Runs));
            
            //Perform and report comparisons between tests
            if (FirstRun.CompareTo(stp.Elapsed)<0)
                Console.WriteLine("Inline Construction Faster: {0:f}", stp.Elapsed.TotalMilliseconds / FirstRun.TotalMilliseconds);
            else
                Console.WriteLine("Refactored Construction Faster: {0:f}", FirstRun.TotalMilliseconds / stp.Elapsed.TotalMilliseconds);

        }

I ran the tests in release mode with iterations of 1, 10, 100 and 1000.

>LinqTest.exe 1  true
Number of Runs: 1
Pre JIT Enabled:  True
Inline  Initialization Test: 00:00:00.0124051 , Average: 00:00:00.0177619
Refactored  Initialization Test: 00:00:00.0121951 , Average: 00:00:00.0174613
Refactored  Construction Faster: 1.02


>LinqTest.exe  10 true
Number of Runs: 10
Pre JIT Enabled:  True
Inline  Initialization Test: 00:00:00.0701888 , Average: 00:00:00.0100497
Refactored  Initialization Test: 00:00:00.0650985 , Average: 00:00:00.0093209
Refactored  Construction Faster: 1.08


>LinqTest.exe  100 true
Number of Runs:  100
Pre JIT Enabled:  True
Inline  Initialization Test: 00:00:00.6291376 , Average: 00:00:00.0090081
Refactored  Initialization Test: 00:00:00.5354964 , Average: 00:00:00.0076673
Refactored  Construction Faster: 1.17


>LinqTest.exe  1000 true
Number of Runs:  1000
Pre JIT Enabled:  True
Inline  Initialization Test: 00:00:06.2699034 , Average: 00:00:00.0089773
Refactored  Initialization Test: 00:00:05.3725538 , Average: 00:00:00.0076925
Refactored  Construction Faster: 1.17

As you can see at 1 iteration there's barely a difference. As we move up the scale the refactored code does consistently outperform the inline expression. This outcome was different from my initial hypothesis. I decided to dig a bit deeper and find out why. So I pulled out ILDasm to see what was going on. I was surprised to see that the IL generated for inline test was twice as long as the refactored test. Looking at the code it became clear what was going on.

Inline IL
 IL_0042:   stloc.3
 IL_0043:   ldloc.3
 IL_0044:   ldc.i4.0
 IL_0045:   ldtoken    method instance void  LinqTest.DataObjects.Order::set_CustomerID(int32)
 IL_004a:   call       class [mscorlib]System.Reflection.MethodBase  [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype  [mscorlib]System.RuntimeMethodHandle)
 IL_004f:   castclass  [mscorlib]System.Reflection.MethodInfo
 IL_0054:   ldloc.2
 IL_0055:   ldtoken    method instance int32  LinqTest.OrderHeader::get_CustomerID()
 IL_005a:   call       class [mscorlib]System.Reflection.MethodBase  [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype  [mscorlib]System.RuntimeMethodHandle)
 IL_005f:   castclass  [mscorlib]System.Reflection.MethodInfo
 IL_0064:   call       class  [System.Core]System.Linq.Expressions.MemberExpression  [System.Core]System.Linq.Expressions.Expression::Property(class  [System.Core]System.Linq.Expressions.Expression,
 class  [mscorlib]System.Reflection.MethodInfo)
 IL_0069:   call       class  [System.Core]System.Linq.Expressions.MemberAssignment  [System.Core]System.Linq.Expressions.Expression::Bind(class  [mscorlib]System.Reflection.MethodInfo,
 class  [System.Core]System.Linq.Expressions.Expression)
Refactored IL
 IL_0005:   stloc.0
 IL_0006:   ldloc.0
 IL_0007:   ldarg.0
 IL_0008:   callvirt   instance int32 LinqTest.OrderHeader::get_CustomerID()
 IL_000d:   callvirt   instance void  LinqTest.DataObjects.Order::set_CustomerID(int32)

The inline call uses reflection on the objects to build the instantiation into the expression tree. It has to load the information about the SQL OrderHeader.CustomerID property via reflection. It then does the same thing for Order.CustomerID on the business object. After that it takes the value loaded from the sql object and binds it to the business object. 

The refactored code skips the reflection entirely. Since the method is expecting an order object LINQ to SQL just needs to do what it does best, load data from the database and map it to the ORM object. The refactored methods just need to do straight property assignment

Now most of this testing was doing with the C# LINQ syntax and not the chained function calls. I'm going to dig a bit deeper and recreate this with pure lambda expressions and see how that stacks up. I have a feeling they will probably perform close to the refactored examples

Another thing that makes me curious is the plateau reached and the differences between 1 to 100 iterations. I have a sneaking suspiscion that some of this maybe related to the JIT compiler and the garbage collector optimizing for the pattern of execution. I'll probably throw in some garbage collection counters to see how different they are.

So for now the moral of the story is refactoring is not only good for code reuse, simplicity it can also help increase performance. Without moving the mapping into another method other calls would have increased JIT time due to having more code than needed. The mapping call only needs to be JITed once.

kick it on DotNetKicks.com
Comments [2] #      LINQ | Performance  |  kick it on DotNetKicks.com Shout it
# Friday, August 22, 2008
by Jeff Klawiter - Friday, August 22, 2008 12:58:20 PM (Central Standard Time, UTC-06:00)
I figured I should mention this. I will be speaking at the Twin Cities Code Camp this fall. My talk is going to be on the PICK/Multivalue systems that are still in use today. It is one of those legacy systems like COBOL that isn't going to fade away anytime soon. IBM actually has taken the lead with it in recent years but modernizing the U2 products (Universe and Unidata).

For the people that don't know Code Camp is a day of talks on whatever speakers want to talk about. It's free and a rather fun time. In the past there have been talks ranging from starting out in ruby, writing custom modules for IIS 7 to hacking a hardware platform to tell you the whether. It is run by Magenic and hosted at New Horizons in Edina (I heard that the next spring one may be moving elsewhere).

Comments [0] #       |  kick it on DotNetKicks.com Shout it
by Jeff Klawiter - Friday, August 22, 2008 12:29:45 PM (Central Standard Time, UTC-06:00)
I was playing around with shaders the other day and found the lack of syntax highlighting in Visual Studio to be a bit annoying. I had downloaded the Nvidia FX composer but it's a bit more complex than I really need. After a bit of searching google I came across InteliShade.NET.

InteliShade seems to have full syntax highlighting and InteliSense for base types. So far the InteliSense support is fairly simple. It will autocomplete object types and function names. It does not detect any variables or structures you've created nor does it give parameter completion on functions. I'm sure this will change as time goes on.

It looks like there's just one guy writing it and also doesn't seem to be open source. I'm sure if there's enough interest he may open things up. I've already begun talking this thing up. It wasn't too long ago Shawn Hargreaves gave a talk at our local XNA user group and he mentioned he didn't know of any VS HLSL sytnax highlighting and urged us to bug the VS team to add it. After finding InteliShade I did send him a quick email through his blog to let him know there is now an option.


Comments [0] #      HLSL | XNA  |  kick it on DotNetKicks.com Shout it
# Monday, August 11, 2008
by Jeff Klawiter - Monday, August 11, 2008 1:20:39 PM (Central Standard Time, UTC-06:00)
Over the weekend I started Reading "CLR Via C#". I picked it up at Borders earlier this year with a certification book. I was trying to get more MCTS certs at the time and never ended up reading it. Also every time I look at it I feel like it's that black box I'll never be able to understand. I realized this is a bad attitude to have, so I opened it up and began reading. Instead of becoming lost, I feel like some things are becoming found.

I realize I should have read this book right away. So far nothing has been entirely over my head. I have had to reread some paragraphs due to sentences being heavy on the the terms. Also the author "Jeff Richter" tries to use the correct CLR terms and they sometimes clash with C# and general OO terms. An example is he uses "type" as the term for a static class.

I've made it 11 chapters in and so far it has been full of those "so thats how that works" and "thats good to know" moments. The biggest one so far has been the Events chapter. He covers a C# feature that has not been covered in any of the C# books I have read.

In C# you can declare Events like Properties. That is instead of using "get" and "set" blocks, one can use "add" and "remove" blocks. He covers this because the default implementation of events in the CLR is a bit flawed when it comes to thread safety. The CLR will lock the full object when adding and removing event delegates. He gives an example of overcoming these flaws by implementing manual locking in the "add" and "remove" blocks.

private event EventHandler<SomeEventArgs> somethingHappend;
private Object mLock = new Object();
public event EventHandler<SomeEventArgs> SomethingHappend
{
    add
    {
        lock (mLock)
        {
            this.somethingHappend += value;
        }
    }
    remove
    {
        lock (mLock)
        {
            this.somethingHappend -= value;
        }
    }
}
As you can see it looks much like a C# property. It uses a private event that is exposed publically through two blocks. Other than the keywords the other major difference is you cannot set access modifers on the "add" and "remove" blocks. It would be very bad programming to let someone add an event delegate but not let them remove it.

I have one application that I maintain where this will come in very handy. Planning on testing out the difference very soon.

I highly recommend this book for any serious .NET developer. I kick myself for not learning more about the CLR in the first place. Visual Studio sometimes babies the programmer too much I think. That and many programmers are lazy and love to just know enough to get by. I find these kinds of programmers have a very hard time working at Sierra Bravo. We have such a large variety of projects that one must learn quickly and know enough to jump the entire gammut of .NET applications. As a .NET developer here it's impossible to just be an ASP.NET developer or WinForms developer. I like it that way, it ensures that I'm never board and am learning all the time.

In my tenure so far I have written, Winforms Applications, entire .NET CF warehouse management applications, fully globalized ASP.NET web sites, various web services, various windows services, System Tray utilities, a Vending Machine controller program (implementing various serial protocols), written TCP clients for propietary protocols and much more. I have also helped companies migrate to/from MSSQL databases with various front ends. Heck, I'm even working on a C++ Win32 mobile application this week. I have done more in 3 1/2 years than a typical programmer does in 10 years.

Understanding how something works makes it much easier to implement a project with it. I found when I was a PHP programmer that I really went from amatuer to professional when I studied how PHP parses the script, allocates memory for variables. This is not an easy thing to do without looking at the source code. There are no good books out there about the "PHP Runtime". Knowing the rammifications of taking advantage of variable variables and not unsetting after use helped me take one of my more complext php programs and reduce it's memory usage 3 fold.

Comments [2] #      C#  |  kick it on DotNetKicks.com Shout it
# Friday, July 04, 2008
by Jeff Klawiter - Friday, July 04, 2008 7:43:41 AM (Central Standard Time, UTC-06:00)
I did a bit of impulse shopping yesterday. I had $15 in reward zone coupons. So I went to Best Buy after work to see if I could find a new mouse to replace my broken MX Revolution. To my dismay they had it for $20 more than what I paid for it at the same store a year ago. I started looking at wireless keyboards as well since my current set up involves a ps2 extender cable and a ps2 to usb converter. After finding the Logitech LX 710 keyboard/mouse combo was pretty nifty I went browsing the PC section. Low and behold I found in the back of the section that have one aisle end with clearance PC's. I have no idea why I haven't noticed this before but I haven't. Most of the PC's there were unboxed due to them being display models.
Comments [0] #      HTPC  |  kick it on DotNetKicks.com Shout it
# Sunday, June 29, 2008
by Jeff Klawiter - Sunday, June 29, 2008 8:14:50 PM (Central Standard Time, UTC-06:00)
While I've heard lots about Unit Testing for years now I've never been able to force myself to implement them. I've always thought it'd take too much time. Time I could have spent writing code, getting work done. Then I go the project I am on now. It is a large project with a very tight deadline. A project that needs to marry different back end sources.

I've been put in charge of architecting the SQL Server back end and the entire middle layer for data access and business objects. I'm using many things I've not had a chance to use before at this scale (LINQ being the largest) in this project so there were many unknowns. The front end may not been done for a bit and I needed to test my data access functions. I decided to bite the bullet and write unit tests.

Normally I would write a small WinForms app to test the most important pieces. This is a dirty approach but it's fast. The biggest hurdle in my mind for Unit Testing was there was no quick way for me to implement and run the tests. Nunit is out there and has some VS integration but whenever I tried it I got confused of where I needed to go to get things done.

Now we have VS 2008 Pro with built in unit testing. While the testing framework included I'm told is decent it's not as good as Nunit. I personally don't care about that. The ability to go to the menu and create unit tests for methods or entire projects on the fly is a godsend for me. VS will create a project for you, include tests for any classes/methods you've selected out of all the projects in your solutions and then do it's best to create close to complete tests.

You can easily step into debug any test and run one or many tests. All the results are saved so they can be examined and compared. While the auto created tests need to be completed I am starting to find that writing to test my code interface is getting cleaner and more too the point. It's much more annoying to pass an object into a method that may only need one or two properties on the object. It's better to make the parameters basic types instead of complex.

The tests have to run against 2 different backends. While one of them will probably not change (the SQL Server) the webservice may end up being replaced. These tests will be invaluable for when that happens. We can then check to see if the new service is acting correctly and if not pinpoint the issues.

by Jeff Klawiter - Sunday, June 29, 2008 7:57:50 PM (Central Standard Time, UTC-06:00)
Documenting code is one of those things that programmers tend to leave out while under a tight dealine or just building a new project. It's one of those things we tend to say, if we have time when we're done we can do it. It can be time consuming and sometimes hard to see the benefit up front. I'm very guilty of poor documentation and commenting. I rarely get to work in a team so I always end up relying on my own memory for what does what and where. Then two years go by and I forget it all.
Comments [0] #      C# | Documentation  |  kick it on DotNetKicks.com Shout it
# Friday, June 27, 2008
by Jeff Klawiter - Friday, June 27, 2008 6:58:48 AM (Central Standard Time, UTC-06:00)
Well I've been working on the new theme for the blog. I have been co-opting the theme from j-maxx.net since it's about the only decent theme I've ever done before. It looks bad in IE due to dashed borders having white space inbetween the dashes instead of the background color.

For some background on the blog. I chose dasBlog as my software due to it having web services built in and has a user base of programmers I look up to. That being said it was originally .NET 1.1 software and the design is getting a bit annoying in some aspects. I'm looking at adding a better syntax highlighter, but adding it so it shows up in all the themes is not straightforward. I may just remove the other themes and only allow this one to simplify things.

I've also noticed that blogs edited after the date they were posted do not show up when you click on the date their were posted in the calendar. I'll have to track that bug down.

All in all it was pretty quick and easy to get the blog up and running. Designing the theme was very easy as well. They did a great job at allowing users to separate design from logic. I'm going to delve more into the templating system to figure out how they did it.

Comments [0] #      blog  |  kick it on DotNetKicks.com Shout it
# Tuesday, June 24, 2008
by Jeff Klawiter - Tuesday, June 24, 2008 6:25:49 PM (Central Standard Time, UTC-06:00)
Well I'm finally opening a real blog. Not sure how much I will be updating this but hey I have a real online presence again. The old J-Maxx Net will stay as it is. Still get a decent amount of traffic on there (kicking myself for not installing adsense years ago).

To start off with.. I love LINQ. I've been looking into it for over a year now but finally have a project where I get to use it fully. C# 3.0 has added so many features I no longer pine for PHP as I once did. Here's a sample below of something I wrote the other day.

            var result = from c in CurrentDataContext.Categories
                         join localinfo in CurrentDataContext.CategoryLocalizationInfos
                            on c.CategoryID equals localinfo.CategoryID
                         where c.CategoryID == CategoryID
                         && localinfo.Language == Language
                         select new Business.Data.Category()
                         {
                             ID = c.CategoryID,
                             Description = localinfo.Description,
                             Languages = GetLanguagesForCategory(c.CategoryID),
                             Name = c.Name,
                             SortOrder = c.SortOrder,
                             Title = localinfo.Title,
                             NavImage = c.NavImage,
                             Language = localinfo.Language,
                             Links = GetLinksForCategory(c.CategoryID, Language),
                             IsDataLoadedFromSql = true
                         };

Comments [0] #      C# | LINQ  |  kick it on DotNetKicks.com Shout it