kenegozi.com

<form id='kenegozi' action='post'></form>

   
2008 Nov 25

[not] storing data in DOM elements - jQuery.data function

tagged as: client-side | tools | Javascript

At time you'd want to store data, related to a DOM element.

 

storing it directly into the element (either by elm.someArbitraryName = value, or with setAttribute) is wacky. Some browsers might not like you using non standard attributes, so you start using things like 'alt' and 'rel'. Then again, these things has meaning, and storing arbitrary data is ... well, uncool to say the least.

 

 

jQuery.data() to the rescue. As jQuery objects are wrappers that HasA DOM elements, and not the DOM elements themselves (as in prototype), storing data on them is like storing data on POJSO (Plain Old JavaScript Objects), and the data() functions allows for an easy way of doing that.

 

Read on that (and of a few other jQuery tips) at http://marcgrabanski.com/article/5-tips-for-better-jquery-code

2008 Nov 10

Delving deeper

tagged as: personal

Took me a little while to set my mind on it, but after doing remote contracting for a year and a half I've had enough of pyjama-driven work, and I started looking for brilliant teams to become part of.

 

In the past I always worked at places where I was, in technical terms at least, *the* leader. At most, I shared that position with Oren Ellenbogen at SQLink for a while, but at the end of the day I always had the ability to veto on technological issues, and people were following my advice on seniority basis.

While contracting, I worked with this amazing start-up company in the UK. They have very experienced and smart people on boards, and it was the first time I found that I really need to fight to get my voice heard. It would be an understatement to say that the satisfaction from knowing this kind of team has accepted my proposals at times is enormous. That's because I was challenged, and needed to lead a change in a place I'm not the CTO/Team-leader of. When at later point we did things according to my suggested (and accepted) design, and was happy to work with it as it was easier and more fun, I was very proud of my work.

 

One more aspect of my past employment is that it was always in small to small-ish teams. at most I was a part of about 10 people R&D department.

 

So what I was looking for now was a company with a large(r) R&D team, with great people with whom I can learn together. A place that is being managed well, that is fun to work for, and that will challenge my skills and push me to learn and evolve.

 

Being the software geek that I am for so many years, and also active in the development community, I am blessed with friends who are holding various positions in R&D departments around the country. This gave me the opportunity to come in to amazing companies, and go through very interesting interviews (that goes *way* beyond abstract-class-vs-interface, testing my design, coding and testing skills, my knowledge in software architecture and problem-solving skills).

 

At the end I picked up www.delver.com. It's a cool startup company with embarrassingly smart people and I'm honoured to be in their ranks.

 

Oh, and they are also using AspView in production from day one ... ;)

 

To new beginnings,

Ken the devler

2008 Nov 7

Taking GoGrid for a spin - first impressions

tagged as: tools

Today I opened a GoGrid account, as I'm looking for quite some time to upgrade my hosted environment.

 

Setting up the account was a breeze, and in a few minutes from starting the process I had a running instance of vs2008 64bit, with IIS and MSSql2005 express.

 

 

 

First impressions:

 

Good:

  • Quick, easy to use control panel, pricing seem reasonable
  • The image contains .net 3.0, and lack some updates so 3.5 was not installing until I allowed all of the windows update stuff to do the magic first.
  • Online chat is helpful and very responsive. I did not need any actual tech help yet though.

Bad:

  • They charge for offline machines, so you can't just turn on and off the machines, but you have to delete machines that are not in use, and in case you want to re-add them you have to recreate a new machine from their image, then running updates, installs, DB setup etc from scratch

 

That's it for now

2008 Nov 2

Google Developer Day 2008

Not tagged yet

I'm attending Google Developer Day 2008 in Israel today. It's my first large non-Microsoft event I'm being at.

 

I'm gonna look into the App Engine track, continuing my interest in the new Microsoft Azure platform. Computing in the cloud is something I consider very important for business applications, and plays nicely with doing SaaS solutions, which is one of my interests lately.

2008 Oct 30

Serving a file from a WCF service

tagged as: c#

Following my post on mini-web server with WCF, I've been asked about how to serve static files (images, stylesheets, scripts).

 

WCF services can return a Stream, so it's just a matter of calling File.OpenRead to get a the stream

 

 

 

 

public Stream GetFile(string file) {

// We forbid access to directories outside of the site root

if (file.Contains("..")) throw new SecurityException(); var ext = Path.GetExtension(file).ToLower().TrimStart('.');

// Just a helper that will

// set WebOperationContext.Current.OutgoingResponse.ContentType

SetContentType(ContentInfo.For(ext)); var filePath = Path.Combine(this.siteRoot, file); return File.OpenRead(GetActualFilePath(filePath)); }

 

 

ContentInfo.For() is a helper for mapping an extension to a mimetype, with a two-stage lookup:

    /// <summary>
    /// Represents info on a given file
    /// </summary>
    public static class ContentInfo
    {
        static readonly KeyValuePair<MimeTypes, string>[] contentInfoFor = new[]
        {
            new KeyValuePair<MimeTypes, string>(MimeTypes.Js, "text/javascript"),
            new KeyValuePair<MimeTypes, string>(MimeTypes.Css, "text/css"),
            new KeyValuePair<MimeTypes, string>(MimeTypes.Html, "text/html"),
            new KeyValuePair<MimeTypes, string>(MimeTypes.Plain, "text/plain"),
            new KeyValuePair<MimeTypes, string>(MimeTypes.Gif, "image/gif"),
            new KeyValuePair<MimeTypes, string>(MimeTypes.Jpeg, "image/jpeg"),
            new KeyValuePair<MimeTypes, string>(MimeTypes.Tiff, "image/tiff"),
        };

        /// <summary>
        /// Gets the mime type for a given <see cref="MimeTypes"/>
        /// </summary>
        /// <param name="mimeType">The file's <see cref="MimeTypes"/></param>
        /// <returns>The file's mime type</returns>
        public static string For(MimeTypes mimeType)
        {
            return (from p in contentInfoFor
                    where p.Key == mimeType
                    select p.Value)
                   .First();
        }

        /// <summary>
        /// Gets the mime type for a given extension
        /// </summary>
        /// <param name="extension">The file's extension</param>
        /// <returns>The file's mime type</returns>
        public static string For(string extension)
        {
            return For(MimeType.For(extension));
        }
    }

 

and

    /// <summary>
    /// Helpers for <see cref="MimeTypes"/> 
    /// </summary>
    public class MimeType
    {
        static readonly KeyValuePair<string, MimeTypes>[] mimeTypeForExtension = new[]
            {
                new KeyValuePair<string, MimeTypes>("js", MimeTypes.Js),
                new KeyValuePair<string, MimeTypes>("css", MimeTypes.Css),
                new KeyValuePair<string, MimeTypes>("htm", MimeTypes.Html),
                new KeyValuePair<string, MimeTypes>("html", MimeTypes.Html),
                new KeyValuePair<string, MimeTypes>("txt", MimeTypes.Plain),
                new KeyValuePair<string, MimeTypes>("gif", MimeTypes.Gif),
                new KeyValuePair<string, MimeTypes>("jpg", MimeTypes.Jpeg),
                new KeyValuePair<string, MimeTypes>("jpeg", MimeTypes.Jpeg),
                new KeyValuePair<string, MimeTypes>("tiff", MimeTypes.Tiff),
            };

        /// <summary>
        /// Selects a <see cref="MimeTypes"/> for a given file extension 
        /// </summary>
        /// <param name="extension">The file's extension</param>
        /// <returns>The file's mime type</returns>
        public static MimeTypes For(string extension)
        {
            extension = extension.TrimStart('.');

            return (from p in mimeTypeForExtension
                    where p.Key == extension
                    select p.Value)
                .First();

        }
    }

 

 

When MimeTypes are:

    public enum MimeTypes
    {
        Js, Css, Html, Gif, Jpeg, Tiff, Plain
    }
2008 Oct 29

Monorail usage poll

Following my last post, I've put up a quick poll for trying to grasp some knowledge about the way people are using (or not using) MonoRail.

 

It's not complete, and there will be further polls as I can already think of questions I have for the community, that did not make their way to this poll, and are very important imo.

 

So, if you care for the future of MonoRail, please do spare some moments to fill in the poll. Be nice and write down your feelings, pain-points and general rants in the text areas. I won't be offended by anything.

 

No personal details will be published (at least not deliberately - and I don't believe anyone will hack into the lousy SQL server it's stored on).

 

so, without further ado, I give you the poll:

 

http://www.kenegozi.com/monorailpoll.html

2008 Oct 29

Introducing Monorail Project

From the mailing list:

... the PMC decided to make a few changes to the Castle Project:
- Projects will be split
- Each project will have a leader (positions open to any committer)
By that we intent to fix our release debt. as having each project running individually allow us to release and document each one of them without dragging/waiting for others.

 

We still haven't decided how to solve dependencies and such, but with time I'm certain we'll be able to come up with solution that will benefit the community.

 

 

ah, and I have been the one appointed as Project Leader for Monorail.

 

Quoting again from the mailing list:

We would expect from the leaders to oversee the development (near and long term), set up goals, roadmaps, coordinate the documentation effort and release it.

 

So my main effort now will be to push a Monorail 1.0 RTM release out of the door. There are many things that need be done before this comes true as in terms of the non-code aspects (like docs, wizards, etc.), Monorail is not as ready as ActiveRecord for example.

 

I will be posting some specific requests for help on the various tasks that will need to be done. I hope that with the aid of the community, we will have a release soon-ish.

2008 Oct 23

Mini web server using WCF

tagged as: c#

I've written a simple application for a friend that monitors the fax machine in his office.

The machine saves incoming messages in the files server, and he needed a way to manipulate the files in various ways.

One of the things he wanted was the ability to present data and allow actions to run over the web. Also

As he's thinking of deploying this on multiple different sites, and would like to be able to set this up easily without configuring web servers etc., and as there's hardly any server-side logic to the UI anyway (the front is JSON consuming jQuery site), and there's a windows service in there anyway for running some recurring tasks, I decided to set up the UI as a WCF service with WebHttpBinding, hosted within the Windows Service.

 

Here's the code for the "Web Server":

 

    /// <summary>
    /// Serving HTTP for the UI
    /// </summary>
    public class WebServer 
    {
        /// <summary>
        /// Access to the current instance of <see cref="WebServer"/>
        /// </summary>
        public static WebServer Current { get; private set; }

        /// <summary>
        /// The current settings
        /// </summary>
        public ISettings Settings { get; private set; }

        private WebServiceHost host;
        private readonly ILogger logger;

        /// <summary>
        /// New WebServer
        /// </summary>
        /// <param name="logger"><see cref="ILogger"/></param>
        /// <param name="settings">Settings</param>
        public WebServer(ILogger logger, ISettings settings)
        {
            this.logger = logger;
            Settings = settings;
            Current = this;
        }

        /// <summary>
        /// Start a new server
        /// </summary>
        public void Start()
        {
            logger.Info("Initialising the web server");
            host = new WebServiceHost(typeof(FaxManagerService), new Uri("http://localhost:" + Settings.WebServerPort + "/"));
            var bindings = new WebHttpBinding();

            host.AddServiceEndpoint(typeof(IFaxManagerService), bindings, "");
            host.Description.Behaviors.Add(new SessionAwareAttribute());

            var sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>();
            sdb.HttpHelpPageEnabled = false;
            
            logger.Info("Starting the web server");
            host.Open();
            logger.Info("The web server was started successfully on port " + Settings.WebServerPort);
        }

        /// <summary>
        /// Restart the server (effectively creating a new service host)
        /// </summary>
        public void Restart()
        {
            Stop();
            Start();
        }

        /// <summary>
        /// Stop the server
        /// </summary>
        public void Stop()
        {
            host.Close();
            host = null;
        }
    }

 

 

the "Web Application" is a WCF ServiceContract named IFaxManaderService.

I'll post about it, and about interesting related stuff later on

2008 Oct 17

Using generic classes and avoid locks

tagged as: c# | D9

In D9.Commons, there's a class responsible for mapping from enum values to their respective description, and vice versa - DescribedEnumHandler.cs

 

The initial API I had in mind was

var enumValue = Enums.From<MyEnum>("The description");

var enumDescription = Enums.ToDescription(MyEnum.Something);

 

The Enums class would hold an IDictionary to map from the given Enum type, to it's DescribedEnumHandler

Then came the question: when should I initialise that map, and how should I allow access to it?

 

Solution 1:

Synchronise access to the map.

Cons: every access to the Enums methods will require synchronisation code.

 

Solution 2:

Allow only one point of initialisation, through a static Initialise(...) method, accepting enum types, or assemblies with enums. This method will be called when the application loads, and after all of the enums are initialised, all the following usages will be lock free.

Cons:

a. It's ugly.

b. You end up creating way too many handlers, even if you won't use most or even any of them.

c. It really is ugly. You don't believe me? look here.

 

Solution 3:

Instead of using Generic methods (From<T> and ToDescription<T>), I changed the Enums class to a generic Enum<T> class.

within the class, there's a single static member, DescribedEnumHandler of T.

Every call to Enum<T> for a new T will instantiate the needed handler, Just In Time.

That's because with generic types, every concrete type is a new type, so List<int> and List<long> are two separate types, without any inheritance relationship between them, so their static members are not shared.

 

That's the class I ended up with:  Enums.cs

2008 Oct 16

Generic types vs. Generic methods - can you tell the difference?

tagged as: c#

 

class Wrapper { public static int Counter{ get; private set;} static Wrapper() { Counter = 0; } public T Get<T>() { ++Counter; return default(T); } } class Wrapper<T> { public static int Counter{ get; private set;} static Wrapper() { Counter = 0; } public T Get() { ++Counter; return default(T);

}

} }

 

"The first uses generic methods while the second is a generic class" is true, but is not what I'm looking for here ...

search page | Blog's home | About me