kenegozi.com

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

   
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 ...

2008 Oct 15

Single and looking

explanation (before the wife kills me): I have some free time in the coming months, so I'm looking for interesting consulting gigs.

 

So, if you're in a company / dev team, and looking for some help with Castle (Windsor, MonoRail), NHibernate, or general information system design and architecture advices or training, setting up build and test environments, or any other of the things I rant about in this blog, then I'm your guy.

I also do web-client ninja work, dancing the crazy css/html/javascript tango (jQuery: yes, Ms-Ajax: no)

 

I currently live in Israel, but I'm fine with going abroad for short terms if you're an off-shore client.

 

you can contact me at "ken@kenegozi.com"

2008 Oct 12

Described Enums in NHibernate

tagged as: c# | nhibernate | D9

First feature in D9.NHibernate: DescribedEnumStringType

 

That's a generic IUserType for mapping enum columns using the descriptions of values instead of their names.

 

It depends on D9.Commons which contains the Described Enum helpers described in an early post

 

Usage:

given the following enum:

using System.ComponentModel;

namespace OpenUni.Domain.Modules
{
    public enum ModuleTypes
    {
        [Description("ר")]
        Standard,

        [Description("מ")]
        Advanced,

        [Description("מס")]
        AdvancedSeminar,

        [Description("תש")]
        Masters
    }
}

 

mapping a field of type ModuleTypes will look like that:

<property
    name    = "ModuleType"
    column  = "ModuleType"
    type    = "D9.NHibernate.UserTypes.DescribedEnumStringType`1[[OpenUni.Domain.Modules.ModuleTypes, OpenUni.Domain]], 
              D9.NHibernate" />

 

or if you use Castle ActiveRecord attributes for mapping:

[Property(ColumnType = "D9.NHibernate.UserTypes.DescribedEnumStringType`1[[OpenUni.Domain.Modules.ModuleTypes, OpenUni.Domain]], D9.NHibernate")]
public virtual ModuleTypes ModuleType {get; set;}

 

 

Code is here:

http://code.google.com/p/d-9/source/browse/#svn/trunk

 

I'll build and upload binaries once I get some time for that. meanwhile you should be able to just svn-co the code, then nant from the root. (assuming nant 0.86b2 and .net 3.5 on the machine)

2008 Oct 12

OSS Licensing - terms and concepts

This is the first post on open source software licensing series. you can find the primer here.

 

I'll start with covering the concepts that I'll use in the following posts:

 

OSI (Open_Source_Initiative)

A bunch of dudes who deal with the approval of open source licenses, according to their ...
http://en.wikipedia.org/wiki/Open_Source_Initiative

The use of OSI Approved licenses is advocated, in order to simplify the whole OSS licensing things.

 

OSD (Open Source Definition)

Look at the linked wiki page. In short, any license that conforms to the principals in this definition is considered an open source license
http://en.wikipedia.org/wiki/Open_Source_Definition

 

Copyleft

A license that requires any code that uses it's covered software, to also apply the same (or similar) license. Also known as "Viral licensing".

http://en.wikipedia.org/wiki/Copyleft
There are different flavours of Copyleft:

 

Strong Copyleft

Every thing that's using the software, either in binary or source form, becomes infected.
Say you write application A, and reference dll B which is licenses with a Strong Copyleft license, then your application A must retain the same license as B.
The only way to avoid being infected is to use the library without linking, such as by calling it through a command line call and parsing the output, or calling the library as an external service through web etc.
Example for a Strong Copyleft license: GPL

Weak Copyleft

Only derivative works must retain the same license. Normally you should be able to reference a binary of a Week Copyleft licensed library, and use your license of choice (as "Code that uses the library")
Examples for Weak Copyleft licenses: LGPL, MPL (Mozilla Public License), Ms-PL (Microsoft Public License)

 

Non-Copyleft

licenses that are not viral, thus are not infecting a client code using them.
Examples: BSD (Berkeley Software Distribution), MIT and ASL (Apache Software License)

 

GPL compatibility

Since GPL is a Strong Copyleft license, it requires that every code which uses a GPL-ed library must become GPL. The obvious thing here is that a software without any open-source distribution cannot be used in a GPL-ed library. There are even some open source licenses that cannot be used with GPL due to restrictions in their licenses. Any open source license that allow licensed software to be used with GPL (that is - to be re-licensed as GPL) is said to be "GPL Compatible"

An example for a non GPL compatible OSS license is IBM's CPL

2008 Oct 12

On Open Source Software Licensing

I happened to discuss Open Source licensing with a few peers lately, and being an active OSS user and committer, they've asked me to write down my take on the matter.

 

It took me a little while to get down to it, but like many other things, doing stuff incrementally seems to be the best option.

 

I'll try to cover the popular licenses. and those I have an opinion about.

 

disclaimer: I am *not* a legal advisor. I have never went to any law school, and the opinions in this series is based only on common sense and my ability to read English. 

 

 

The first post in the series is OSS Licensing - terms and concepts

2008 Oct 11

D9 - Yet another tools project

tagged as: tools

I've started a new oss project under the name "D9".

 

the project is hosted at http://code.google.com/p/d-9/

 

I'm adding all kinds of useful stuff I've written during my years doing .NET, that I didn't have any better place for.

 

It's fairly empty now, but during the following days I hope to add more stuff in there.

 

Currently you can find:

  • D9.Commons - well, common stuff. Things that need no reference outside the BCL.
    Currently the only thing there is a helper for using the DescriptionAttribute on enum values. more to come
  • D9.NHibernate - helpers for NHibernate development.  The only thing there currently is a UserType that allow persisting enums using their DescriptionAttribute instead of their name
  • D9.StaticMapGenerator - I've written about this before. It's a command-line tools that generates a strongly type sitemap for a website's static files (css, js and image files)

What I'm gonna add shortly:

  • D9.QuerySpecBuilder - a library for generating SQL code in a structured Criteria-like manner

 

I generally am doing this so I'll have a place for all my recurring stuff (instead of copy&pasting from project to project every now and then). If people will find it useful it'd be great. If people will want to contribute to it it'd be even greater.

 

License is "new BSD" so feel free to use it if you like

 

comments, endorsements and insults are welcome as always.

2008 Oct 10

Described Enums 2.0

tagged as: c#

As part of my university seminar, I found myself writing this little enum:

 

using System.ComponentModel;

namespace OpenUni.Domain.Modules
{
    public enum ModuleTypes
    {
        [Description("ר")]
        Standard,

        [Description("מ")]
        Advanced,

        [Description("מס")]
        AdvancedSeminar,

        [Description("תש")]
        Masters
    }
}

 

If you can't read Hebrew then for the sake of this post, the following is applicable:

 

using System.ComponentModel;

namespace OpenUni.Domain.Modules
{
    public enum ModuleTypes
    {
        [Description("A standard module")]
        Standard,

        [Description("An advanced module")]
        Advanced,

        [Description("An advanced seminar")]
        AdvancedSeminar,

        [Description("Module in a Masters course")]
        Masters
    }
}

 

You want the description of a given value, or to parse a given description string (say from the DB) to get the value it represents.

Many code bases I've seen contains an EnumHelper class or a variation of one, which allow just the same. Many of these use un-cached reflection to achieve that. As in my scenario this mapping will happen many (I mean *many*) times, I thought about making it a bit more agile.

 

Here's what I got:

 

using System; using System.Collections; using System.Collections.Specialized; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection; namespace NHibernate.Type

{ /// <summary> /// Allow access to enum values with /// <see cref="DescriptionAttribute">DescriptionAttribute</see> /// set on them /// </summary> public static class DescribedEnumHandlers { private static readonly IDictionary handlers = new ListDictionary(); /// <summary> /// Initialises enum types to be used with the <see cref="DescribedEnumHandlers"></see> /// </summary> /// <param name="assemblies">The assemblies to grab described enums from</param> public static void Initialise(params Assembly[] assemblies) { Initialise((IEnumerable<Assembly>)assemblies); } /// <summary> /// Initialises enum types to be used with the <see cref="DescribedEnumHandlers"></see> /// </summary> /// <param name="assemblies">The assemblies to grab described enums from</param> public static void Initialise(IEnumerable<Assembly> assemblies) { var titledEnums = from assembly in assemblies select assembly into a from type in a.GetTypes() where type.IsEnum && (from f in type.GetFields() where f.GetCustomAttributes(typeof (DescriptionAttribute), false).Length == 1 select f ).Count() > 0 orderby type.FullName select type; foreach (var type in titledEnums) { handlers.Add(type, new DescribedEnumHandler(type)); } } /// <summary> /// Extract the description for a given enum value /// </summary> /// <param name="value">An enum value</param> /// <returns>It's description, or it's name if there's no registered description for the given value</returns> public static string EnumToDescription(object value) { var handler = handlers[value.GetType()] as DescribedEnumHandler; return handler != null ? handler.GetDescriptionFrom((Enum)value) : value.ToString(); } /// <summary> /// Gets the enum value for a given description or value /// </summary> /// <typeparam name="T">The enum type</typeparam> /// <param name="stringValue">The enum value or description</param> /// <returns>An enum value matching the given string value, as description (using <see cref="DescriptionAttribute">DescriptionAttribute</see>) or as value</returns> public static Enum ToEnumValue<T>(this string stringValue) where T :struct { var type = typeof (T); var handler = handlers[type] as DescribedEnumHandler; return handler != null ? handler.GetValueFrom(stringValue) : (Enum)Enum.Parse(type, stringValue, false); } /// <summary> /// Used to cache enum values descriptions mapper /// </summary> private class DescribedEnumHandler { private readonly IDictionary<Enum, string> toDescription = new Dictionary<Enum, string>(); private readonly IDictionary<string, Enum> fromDescription = new Dictionary<string, Enum>(); public DescribedEnumHandler(Type type) { var enumEntrys = from f in type.GetFields() let attributes = f.GetCustomAttributes(typeof(DescriptionAttribute), false) where attributes.Length == 1 let attribute = (DescriptionAttribute)attributes[0] select new { Value = (Enum)Enum.Parse(type, f.Name), attribute.Description }; foreach (var enumEntry in enumEntrys) { toDescription[enumEntry.Value] = enumEntry.Description; fromDescription[enumEntry.Description] = enumEntry.Value; } } public string GetDescriptionFrom(Enum value) { return toDescription[value]; } public Enum GetValueFrom(string title) { return fromDescription[title]; } } } }

 

Usage:

DescribedEnumHandlers.Initialise(typeof(ModuleTypes).Assembly);

Console.WriteLine(DescribedEnumHandlers.EnumToDescription(ModuleTypes.Standard));
Console.WriteLine("ר".ToEnumValue<ModuleTypes>());

 

Next time I'll show you how I made it play nicely with NHibernate

 

 

* code is licensed as BSD if you wish to use it

2008 Oct 7

Where is Ayende?

tagged as: personal

I mean, see how dependant on rss I became.

 

I'm doing my blog reading through google reader and I'm quite happy with it. One of the first blogs I was subscribed to is Ayende's. This dude usually post about 100 articles a day, so it's a safe bet to see him in the Unread list when I fire up reader to help my morning coffee down the throat.

 

At 17 Sep. I stopped finding new posts there, knowing Oren personally, I knew he was doing some off-shore consulting gigs and I figured he had little time for that.

 

I even remember a certain known figure in the .NET OSS world who have asked me to try and visit Oren in his home, as this dude was worried due to the unlikely low profile on his blog for some time ...

I did reach him then by email and that was enough to prove he's alive and well, but I didn't think about asking him on the matter of the silence on the blog feed.

 

Today I opened up his blog to look at something in his blog's layout and the first thing that I noticed was that there's a new layout. Then I found that there are many new posts, which I did not get to my reader.

 

 

Apparently what happened is that the feed is being burned via feedburner now, and I was looking at his old Dasblog based feed endpoint, and the redirect from there is probably no more in place.

 

 

Lesson I've learned: pop onto my favourite bloggers' sites from time to time.

2008 Oct 5

That's a better demo code

tagged as: c#

Lately I ranted a bit about the responsibility of community leaders, to not present totally crappy code, at least not without a disclaimer.

 

This is a better way of doing that. Another great post from Mike.

 

I might have also try-catch-ed the

(HttpWebRequest)WebRequest.Create(url)
bit, but anyway that's good code for people to copy&paste into their project without leaving HttpWebResponses and other Streams in danger of hanging loose.
2008 Oct 2

Fake data for People table

tagged as: SQL
Task

Populate People table with fake data for demo purposes.

Assume the relevant tables look like that:

People (Id, LastName, FirstName, CityId)
Cities (Id, Name)

 

Step 1 - getting names

I created a database called Useful, with two tables: FirstNames and LastNames.

Filled each with first and last names, that I found off sites in the internet.

I managed to get 808 first names, and 742 last names.

 

Step 2 - generating the data

I wanted to fill the People table with the Cartesian Product of both name tables.

Out of 808 first names and 742 last names I'd get 599,536 rows using

SELECT
    f.Name AS FirstName,
    l.Name AS LastName
FROM
    FirstNames f,
    LastNames l

But I'd also like to have the CityId populated, with a random city.

The naive approach is

SELECT
    f.Name AS FirstName,
    l.Name AS LastName,
    (SELECT TOP 1 Id FROM City ORDER BY NEWID()) AS CityId
FROM
    FirstNames f,
    LastNames l

But the ORDER BY NEWID() bit is happening once for the whole select, so you end up with the same CityId for all you rows.

 

My end solution was:

INSERT INTO People (FirstName, LastName, CityId)

SELECT FirstName, LastName, CityId FROM ( SELECT ROW_NUMBER() OVER (ORDER BY l.Name, f.Name) AS ROW, f.Name AS FirstName, l.Name AS LastName FROM Useful.dbo.LastNames l, Useful.dbo.FirstNames f ) AllNames, ( SELECT Id AS CityId, ROW_NUMBER() OVER (ORDER BY NEWID()) AS ROW FROM Cities ) C WHERE AllNames.ROW % 66 = C.ROW % 66

Let's go over it:

1. I add a ROW column to the "all names" temp-table. Due to the ORDER BY NEWID()) I'll get a new sort on every select, so the ROW column is random enough.

2. I add a ROW column to the Cities table. Same kind of randomness as 1

Now I inner join the tables on the ROW column on both tables, mod the number of possible cities (which is less than the names count), getting a random CityId for each row in the "all names" table (which is the Cartesian Product of FirstNames and LastNames)

2008 Oct 2

Happy new year, here comes SQL

tagged as: nhibernate | hql | SQL

One of the things occupyin