November 2007 Entries
Visitor Pattern for User Interface and Display

I was browsing the NHibernate forums and came across a post by "thatmikewilliams" who posted the following code:

--------------------------------------------------------

Because this functionality is closely tied to the user interface you should probably use a visitor for this (rather than an overridden method in your class hierarchy).

package test.visitor;
public abstract class Payment {
   interface Visitor {
      Object visit(CardPayment payment);
      Object visit(CashPayment payment);
   }
   public abstract Object accept(Visitor visitor);
}

package test.visitor;
public class CardPayment extends Payment {
   @Override
   public Object accept(Visitor visitor) {
      return visitor.visit(this);
   }
}

package test.visitor;
public class CashPayment extends Payment {
   @Override
   public Object accept(Visitor visitor) {
      return visitor.visit(this);
   }
}

package test.visitor;
public class PaymentDisplayStringVisitor implements Payment.Visitor {
   public Object visit(CardPayment payment) {
      return "CC";
   }
   public Object visit(CashPayment payment) {
      return "CS";
   }
}

package test.visitor;
import java.util.ArrayList;
import java.util.List;
public class Test {

   public static void main(String[] args) {
      List<Payment> payments = new ArrayList<Payment>();
      payments.add(new CashPayment());
      payments.add(new CardPayment());
      
      PaymentDisplayStringVisitor visitor = new PaymentDisplayStringVisitor();
      for (Payment payment : payments) {
         System.out.println(payment.accept(visitor));
      }
   }
}

----------------------------------------------

Using the Visitor Pattern to display domain specific types on a user interface is a nice approach instead of overriding specific methods on your domain object, on top of that, cluttering your domain objects with useless "UI" specific methods like ("get object name").  Pretty interesting approach. :)  Notice the PaymentDisplayStringVisitor returns specific string type based on the type.  Very Cool.  I'll try extending this approach using .NET and Generics and post some code later.

CSharp Polymorphism, Inheritance, Method Hiding, and Method Overriding

Classes that declare virtual methods allow inheritors to permanently replace the method with their own implementation regardless of type cast.  So, if Class A defines Xoo() as virtual, then any class inheriting from A, overriding Xoo(), the inheritor's Xoo() will be called regardless of wether the variable is treated or typecasted to A.

If you use the 'new' keyword (Method Hiding), then whether or not the declared method is called directly depends on how a variable is being used.

For example, consider:

namespace InheritanceTest

{

    class A

    {

        public virtual void Xoo(){ Console.WriteLine( "A::Xoo()" ); }

        public void Yoo(){ Console.WriteLine( "A::Yoo()" ); }

    }

    class B : A

    {

        public override void Xoo(){ Console.WriteLine( "B::Xoo()" ); }

        private new void Yoo(){ Console.WriteLine("B::Private Yoo()"); }

    }

    class BB : A

    {

        public override void Xoo(){ Console.WriteLine("BB::Xoo()"); }

        public new void Yoo(){ Console.WriteLine( "BB::Yoo()" ); }

    }

    class C : A

    {

        public virtual new void Xoo(){ Console.WriteLine( "C::Xoo()" ); }

        public virtual new void Yoo(){ Console.WriteLine( "C::Yoo()" ); }

    }

    class D : C

    {

        public override void Xoo(){ Console.WriteLine( "D::Xoo()" ); }

        public override void Yoo(){ Console.WriteLine( "D::Yoo()" ); }

    }

 

    class Program

    {

        static void Main( string[] args )

        {

            A a = new A();

            a.Xoo();   //A::Xoo()

            a.Yoo();   //A::Yoo()


 

 

            B b = new B();

            b.Xoo();   //B::Xoo()

            b.Yoo();   //A::Yoo()<- Private 'new' B.Yoo() is

                       //           not available so A.Yoo() is called



 

 

            A ab = new B();

            ab.Xoo();  //B::Xoo()<- B.Xoo() override replaces

                       //           virtual A.Xoo() regardless of cast.

            ab.Yoo();  //A::Yoo()



 

 

            BB bb = new BB();

            bb.Xoo();  //BB::Xoo()

            bb.Yoo();  //BB::Yoo()<- If used directly as BB,

                       //            then 'new' BB.Yoo() hides A::Yoo()



 

 

            A abb = new BB();

            abb.Xoo(); //BB::Xoo()

            abb.Yoo(); //A::Yoo();<- If casted and used as A, then A::Yoo()


 


           
C c = new C();

            c.Xoo();   //C::Xoo()

            c.Yoo();   //C::Yoo()



 

 

            A ac = new C();

            ac.Xoo();  //C::Xoo()

            ac.Yoo();  //C::Yoo()



 

 

            D d = new D();

            d.Xoo();   //D::Xoo()

            d.Yoo();   //D::Yoo()



 

 

            C cd = new D();

            cd.Xoo();  //D::Xoo()

            cd.Yoo();  //D::Yoo()



 

 


            A ad = new D();

            ad.Xoo();  //A::Xoo()

            ad.Yoo();  //A::Yoo()

        }

    }

}

Add Comment Filed Under [ C# ]
NHibernate - null id in entry (don't flush the Session after an exception occurs)

imageI ran into this issue today when trying to persist one of my objects.  The cause of the problem was interesting.  I was trying to save an object when a property/columns in the table had a unique constraint.  As a result, the object that I was trying to persist would not persist simply because the object's property it failed to meet the unique constraint.

As a result, a call to Save() on the object failed and the ID on the object I was trying to save was not set, but NHibernate still processed the object and associated it with its persistence mechanism leaving it in a "semi-persistent" state with the NHibernate persistence manager (ie: NHibernate now knows about the object you tried to save and it SHOULD have fully evicted the object from its persistence manager because the save failed, but it didn't).

When an HTTP request finishes on my ASP.NET application, I flush and close all NHibernate session objects at the time the request is done.  And as a result, when the HTTP request finished, NHibernate attempted to flush the jacked up "semi-persistent" object (an object who's ID was null) and ultimately generating the error above.

So, the solution that I implemented was to wrap the Save() in a try{} catch{} statement, and if the save failed, immediately close and shutdown the session, handle the error/exception.  Then, check if Session.IsOpen when the HTTP request finishes.

Hope that helps, confused0081.gif

Brian Chavez

Remove Windows Service

You can remove windows services by executing the following command:

C:\> sc delete [service name]

TIP:  If you don't know the service name you're trying to delete, you can find it by going to Start>Run>services.msc and locate the service name in the service's property page.

image

2 Comments Filed Under [ Tips & Tricks ]
Windows 2003 & .NET Remoting, CruiseControl.NET, SVN, Freezes, Lockups, and Stalls with localhost - ZoneAlarm at Fault

image image

I've been having a problem on my servers for a few months now that would occasionally "creep up" from time to time.  Applications would freeze up running after running a .NET application that uses .NET remoting (like CuriseControl.NET).  Other times, I've had SVN.exe (Win32 build) lockup when connecting to localhost.  The problem I was having went something like this:

  • I would start an application that connected to localhost.
  • The application would attempt to make a connection to localhost.
  • TcpView would show the connection being made and established.
  • Once the application established a connection on localhost, all Operating System functions would come to a grinding halt.  Any attempt to launch any new processes would fail.  For example, if I started notepad from Start>Run... explorer would have accepted the command and the run box would have dissapeared, only that it seemed like the application launch was "queued".  Notepad would not run until I closed the connection that was being made in TCPView.

Really weird behavior, until I started uninstalling things from the server one by one.  My first target was the JAVA6 runtime, my second target was ZoneAlarm.  After I uninstalled ZoneAlarm 6.5.737.000, everything started working beautifully.  Now, I bet CurseControl.NET will work. :)

If you ever have problems with the operating system locking up when an application attempts to connect to localhost and you have ZoneAlarm installed, good chances are, ZoneAlarm (with its drivers working in kernel mode) are the root cause of the problem.

WMI Provider Error - Access Denied - TDSSNIClient initialization failed with error 0x5

imageI got an interesting error while trying to change the log on service account for SQL server.  I got a "WMI Provider Error" and a bunch of errors in the Windows Event Log.

Simple solution:

Restart.

The problem is simply, a Named Pipe issue.  Restarting re-creates the Named Pipe under the correct log on account.

 

 

 

 

If the restart fails, and you're still having problems connecting to SQL Server Remotely, try the following:

  • Set the log on account permissions on:

    C:\Program Files\Microsoft SQL Server
    C:\DATA DIRECTORY

    for the log on account.  You'll need to set "Full Control" permissions and make sure that you re-apply the rule to all children by clicking on the directory properties>Security>Advanced>Permissions>"Replace permission entries on all child objects..."

Hope that helps.

PNG Transparency and Cross Browser Compatibility

image If you are dealing with web-development, PNGs, and transparencies, this neat little trick should help.  Cross browser compatibility and support for PNGs isn't that good between IE5, IE6, IE7 and other browsers.  But there are some tricks you can do to help minimize PNG transparency problems while maximizing cross browsers compatibility.  The best technique that I've found for working with PNG transparencies is to use Adobe Fireworks to create PNG-8 images with "Alpha Transparency" indexes.  This eliminates the need for JavaScript/Filter Hacks to make PNG transparencies work correctly.  Here's the SitePoint article on how to do just that.

 


NOTE: I copied the following from the SitePoint article.  For some reason, Sunday 2:00AM 3/22/09 their servers were down and couldn't access the article.  So I pulled a cached version and appended it to this blog post to avoid loosing this gem article forever.  If the site point link article works, please use it instead (I'm sure they want their Ad revenue.)


By Alex Walker

I ran through this little Fireworks PNG trick in the Design View this morning and thought it was worth dropping in a blog post too. This is a method that’s been around for years, but I’m constantly surprised by how many people don’t know about it. Even in this office, I’ve had web gurus furrowing their brows and insisting “No, no … that can’t be right … can it?

So, at the risk of having long-time Fireworks users yawn, roll their eyes and think duh!, here it is.

As you probably already know, PNG comes in two flavors — 8-bit and 32-bit. It’s the 32-bit version that gets most of the fanfare.

PNG32’s major characteristics are:

  • It uses a flexible “JPEG-like” RGB color model, rather than a limited palette as GIF does.
  • It employs a completely lossless compression method, allowing you to save and resave your image with no loss of quality.
  • Lossless compression does come at some cost — PNG images are always much fatter than their JPEG equivalents.
  • It can reproduce complex, graded transparency settings, similar to a PSD or TIF file.

Of course, Microsoft’s scant regard for the PNG spec (authored way back in 1996) meant that the announcement of the glorious PNG format fell on deaf ears. And rightly so — as Internet Explorer was steadily grinding it’s way to a 95% share of the browser market, naturally an image format that rendered transparency as a solid, dishwater grey for most users qualified as a total non-event for the majority of developers.

Not to be bowed, a lot of bloodyminded developers set about inventing all manner of hacks, tricks and workarounds designed to force IE to play nice. These included many JavaScript/IE Filter-based solutions and even a Flash powered PNG renderer.

While most of these methods worked, all of them were complex, completely tied to the presence of another technology (Flash, JavaScript, etc.), and still failed badly on older browsers.

These efforts were, however, good attempts at making the best of a bad situation.

PNG8’s major characteristics are:

  • It employs a palette-based color model (sometimes called an indexed palette), like the one that GIF uses.
  • It can’t animate like GIF.
  • It offers GIF-like 1-bit transparency. Pixels are either solid or completely transparent, but never partially see-through.

Although this last point is generally accepted as fact, it isn’t strictly true, and this is the topic we’ll be examining today.

Transparency information for all PNGs is contained in a section of the file called a chunk, and according to the spec, for indexed images, it stores alpha channel values for one or more palette entries.

In other words, the chunk is allowed to have more than one transparency color.

Now, as we know, official specs can lay out all sorts of wonderful ideals involving rainbows and unicorns and fluffy kittens — just look at the most of W3C specs — but it’s what happens in the big, wide, dirty world that truly matters.

Let’s look at an example.

image

We’ll begin in Fireworks with a simple illustration that I’ve given a yellow translucent glow. As you can see in the screenshot below, the background is visible through the glow.

If we set our file format to PNG8 - indexed transparency, we get a result very much like any transparent GIF you might see. One color chip in our palette is set aside for the alpha channel, and all semi-transparent colors are flattened into the background color and rendered opaque.

image

However, if we switch from index to alpha transparency, things get interesting.

image

While our default alpha chip is still there in the top left corner, our PNG8 palette preview now shows a new type of color chip with a transparent chiplet cut out of the top-left corner. These are our semi-transparent colors.

Let’s export the graphic and see what our web browsers make of it. If you want to try your own quick tests, the page is here.

image

As you can see in the diagram above, all four modern browsers render the yellow glow effect beautifully, with subtly varying levels of transparency. No issues there.

But what about those cranky older IEs? Are they going to suck the life out of the party again?

The answer is: not necessarily.

image

Granted, older browsers won’t render the gentle glow effect, they’ll happily ignore it while continuing to render the 100% transparent parts in glorious, GIF-like, 1-bit alpha. Not perfect, but not tragic either — particularly when compared to the ugly grey boxes that accompany unhacked PNG32s on older versions of IE. Keep in mind that all the IE filter based PNG hacks still leave a grey box in IE5.

Amazingly, Fireworks seems to be the only graphics app that supports this semi-transparent PNG8 export feature — and it has done so since at least version 3.

I can certainly confirm that none of PhotoShop, Gimp, Paintshop Pro, or Xara has this functionality built-in. Since I first published this in the DV, forum member Danieljames has reported that two small apps — pngquant and pngnq — can mimic this trick. However it appears that Fireworks does a better job, so obviously if you have even an older version of Fireworks hanging around, it’s probably worth holding onto just for this feature!

Summary

It seems there are very few reasons for not using more 8-bit Fireworks PNGs in our work. In many typical situations, between 60% and 80% of users will be using a browser that fully supports these files.

image

The remaining IE5-6 users will see a slightly jaggier but often very acceptable version of the same image. The example to the right is used on the sitepoint.com home page, and I doubt IE6 users are aware that they’re missing anything.

The generated files are small — the light globe image used in the examples above was less than 6k. I generated a PNG32 version of the same image and it was 3 times the size.

And as they have no reliance on browser hacks, JavaScript, Flash, DirectX, or any other third-party technology, it’s difficult for them to fail.

While there still may be times when full transparency control in all browsers will demand the PNG32 hacks, personally I think PNG8 should become the default choice for web transparency effects.

AJAX and ASP.NET Template Controls

I was programming today (err. early morning, 1:00 AM) and stumbled across this error:

[NullReferenceException: Object reference not set to an instance of an object.]

   AjaxControlToolkit.ExtenderControlBase.LoadClientStateValues() in d:\E\AjaxTk-AjaxControlToolkit\Release\AjaxControlToolkit\ExtenderBase\ExtenderControlBase.cs:332

   AjaxControlToolkit.ExtenderControlBase.Page_PreLoad(Object sender, EventArgs e) in d:\E\AjaxTk-AjaxControlToolkit\Release\AjaxControlToolkit\ExtenderBase\ExtenderControlBase.cs:287

   System.EventHandler.Invoke(Object sender, EventArgs e) +0

   System.Web.UI.Page.OnPreLoad(EventArgs e) +86

   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +948

AJAX apparently blew chunks.  After taking a look at the AJAX source code ExtenderControlBase.cs (thank goodness it's open source), the LoadClientStateValues() was trying to load some hidden client state data stored in a hidden control being resolved by FindControl() method on NamingContainer.  Well, because I was using my AJAX control in a LayoutTemplate, NamingContainer tuned out to be null which was causing ASP.NET's OnPagePreload -> LoadClientStateValues() to fail.

Here was the offending code:

<asp:Login ID="Login2" runat="server" OnLoginError="Login2_LoginError">

    <LayoutTemplate>

            <fieldset>

                <div class="panel-username">

                    <p>

                        <asp:Label ID="UserNameLabel" runat="server" AssociatedControlID="UserName" CssClass="labeltext bold">Email Address:</asp:Label>

                        <asp:TextBox ID="UserName" runat="server" CssClass="textbox"></asp:TextBox>

                        <ajax:TextBoxWatermarkExtender ID="TextBoxWatermarkExtender1" runat="server" TargetControlID="UserName"

                            WatermarkText="Enter Email Address" WatermarkCssClass="watermark">

                        </ajax:TextBoxWatermarkExtender>

                        <asp:RequiredFieldValidator ID="UserNameRequired" runat="server" ControlToValidate="UserName"

                            ErrorMessage="User Name is required." ToolTip="User Name is required." ValidationGroup="ctl00$Login2">*</asp:RequiredFieldValidator>

                    </p>

                </div>

                <div class="panel-password">

                    <p>

                        <asp:Label ID="PasswordLabel" runat="server" AssociatedControlID="Password" CssClass="labeltext bold">Password:</asp:Label>

                        <asp:TextBox ID="Password" runat="server" TextMode="Password" CssClass="textbox"></asp:TextBox>

                        <asp:RequiredFieldValidator ID="PasswordRequired" runat="server" ControlToValidate="Password"

                            ErrorMessage="Password is required." ToolTip="Password is required." ValidationGroup="ctl00$Login2">*</asp:RequiredFieldValidator>

                    </p>

                </div>

                <div style="float: left; width: 150px;">

                    <p>

                        <span class="bold">Don't have an account?</span> <a id="A1" href="~/common/SignUp.aspx"

                            runat="server">Register here</a>. It's easy and free!</p>

                </div>

                <div class="panel-button">

                    <p>

                        <asp:ImageButton ID="LoginButton" runat="server" CommandName="Login" ValidationGroup="ctl00$Login2"

                            ImageUrl="~/Images/TransparentPixel.gif" CssClass="cmdSignIn" />

                    </p>

                    <p style="padding-top: 10px;">

                        <a href="#">Forgot password?</a></p>

                </div>

            </fieldset>

    </LayoutTemplate>

</asp:Login>

As you can see, the offending line of code is marked in bold above.  I was using the TextBoxWatermarkExtender on the UserName TextBox control.  Since AJAX needs a NamingContainer, a simple work around is to simply wrap the code in a ASP.NET Panel control, and you're problems will go away like so:

<asp:Login ID="Login2" runat="server" OnLoginError="Login2_LoginError">

                    <LayoutTemplate>

                        <asp:Panel ID="panWrapper" runat="server">

                            <fieldset>

                                <div class="panel-username">

                                    <p>

                                        <asp:Label ID="UserNameLabel" runat="server" AssociatedControlID="UserName" CssClass="labeltext bold">Email Address:</asp:Label>

                                        <asp:TextBox ID="UserName" runat="server" CssClass="textbox"></asp:TextBox>

                                        <ajax:TextBoxWatermarkExtender ID="TextBoxWatermarkExtender1" runat="server" TargetControlID="UserName"

                                            WatermarkText="Enter Email Address" WatermarkCssClass="watermark">

                                        </ajax:TextBoxWatermarkExtender>

                                        <asp:RequiredFieldValidator ID="UserNameRequired" runat="server" ControlToValidate="UserName"

                                            ErrorMessage="User Name is required." ToolTip="User Name is required." ValidationGroup="ctl00$Login2">*</asp:RequiredFieldValidator>

                                    </p>

                                </div>

                                <div class="panel-password">

                                    <p>

                                        <asp:Label ID="PasswordLabel" runat="server" AssociatedControlID="Password" CssClass="labeltext bold">Password:</asp:Label>

                                        <asp:TextBox ID="Password" runat="server" TextMode="Password" CssClass="textbox"></asp:TextBox>

                                        <asp:RequiredFieldValidator ID="PasswordRequired" runat="server" ControlToValidate="Password"

                                            ErrorMessage="Password is required." ToolTip="Password is required." ValidationGroup="ctl00$Login2">*</asp:RequiredFieldValidator>

                                    </p>

                                </div>

                                <div style="float: left; width: 150px;">

                                    <p>

                                        <span class="bold">Don't have an account?</span> <a id="A1" href="~/common/SignUp.aspx"

                                            runat="server">Register here</a>. It's easy and free!</p>

                                </div>

                                <div class="panel-button">

                                    <p>

                                        <asp:ImageButton ID="LoginButton" runat="server" CommandName="Login" ValidationGroup="ctl00$Login2"

                                            ImageUrl="~/Images/TransparentPixel.gif" CssClass="cmdSignIn" />

                                    </p>

                                    <p style="padding-top: 10px;">

                                        <a href="#">Forgot password?</a></p>

                                </div>

                            </fieldset>

                        </asp:Panel>

                    </LayoutTemplate>

                </asp:Login>

Now it works :)  Hope that helped anyone running into the same problem.  Whenever you're dealing with ASP.NET template controls, and you're using AJAX within these template controls, be sure to wrap the control pointed to by TargetControlId & the AJAX control itself in it's own naming container to avoid issues like this.  Another bug down fighting0028.gif. :)

2 Comments Filed Under [ Tips & Tricks Errors ]