kenegozi.com

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

   
2008 Jul 21

Patch management approaches using decent CSM

tagged as: tools | Source Control

Following Ayende's post on Patch management approaches using centralized SCM, here are how I would have dealt with the 4 issues that he brings up, using a Decentralised SCM.

 

I use git, so I'll use git terms here. I guess it's quite similar for other DSCM systems.

 

Note that I haven't used patches on git development as until now all of my git work was on repositories I had write access to, However the principals are the same (i.e. - all of the tree is local to my machine, thus I can reach any point in the history locally).

 

First I'll clone the hosted repository to my local machine.

  • #1
    I'd have created a separate local feature branch for each feature, so separating the patches is easy
  • #2
    again, I can do this in two separate local branches, so I do not need to "revert and apply" when I move between the two. I also get to have a complete SCM experience, not only a single patch/step per feature.
    I can also have a third branch, combining the work of the two feature branches, for my own use
  • #3
    the second feature's branch would be based on the first one. should the first need some rework that is important to the second, it'd be easy to apply changes on the first, then rebase the second ontop of the updated first
  • #4
    just two commits on the same branch.

So, using a DSCM, I can work locally with the benefits of a SCM, have as many branches/features as I want. the whole tree is stored locally, and its blazing fast to switch branches, so I can easily work on every aspect I want, and easily create a patch from every node in the history tree, to send to the project owners.

2008 Jun 22

Castle.Tools.* in Castle Contrib's repository has moved a bit

tagged as: css | html | tools | castle | SQL Server

The tools (various small helper libraries) are now under http://svn.castleproject.org:8080/svn/castlecontrib/Tools/

 

what's in there:

  1. Castle.Tools.StaticMapGenerator - That one creates a typed tree representing js/css/image files on the site's filesystem.
    more here:
    http://www.kenegozi.com/Blog/2008/01/17/staticmapgenerator-for-asp-dot-net-first-teaser.aspx
    Which reminds me that I need to add .swf files to the mix ...
  2. Castle.Tools.SQLQueryGenerator -  That one is for building plain old SQL strings in a typed and intellisense friendly way.
    more here:
    http://www.kenegozi.com/Blog/2008/01/27/already-added-stuff-to-sql-query-generator.aspx
  3. Castle.Tools.QuerySpecBuilder/ - The new kid in the block. That's a tool that is used to build specs programmatically, which would later be translated to a SQL string for your flavour of DAL. The generated SQL is mostly ANSI compliant, apart from the Paging syntax which is TSQL only currently, but at some point I'll add an extension point to allow other syntaxes.
    I also have an external thing to make it extremely useful with NHibernate's ISQLQuery.
    I'll blog about all that when I'll have a little time.
2008 Jun 22

Simple String Hashing in .NET

tagged as: c# | tools

I've been asked about it several times lately, so I'll just put here an oldie that I've been using for a few years now untouched:

 

   1:  // MIT license
2: // Copyright 2005-2008 Ken Egozi
3: //
4: // Permission is hereby granted, free of charge, to any person obtaining a copy
5: // of this software and associated documentation files (the "Software"), to deal
6: // in the Software without restriction, including without limitation the rights
7: // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8: // copies of the Software, and to permit persons to whom the Software is
9: // furnished to do so, subject to the following conditions:
10: //
11: // The above copyright notice and this permission notice shall be included in
12: // all copies or substantial portions of the Software.
13: //
14: // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15: // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16: // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17: // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18: // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19: // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20: // THE SOFTWARE.
21:  
22: using System;
23: using System.Collections.Generic;
24: using System.Text;
25: using System.Security.Cryptography;
26: using System.Collections;
27:  
28: namespace KenEgozi.CryptographicServices
29: {
30: public static class Hashing
31: {
32: private static Hashtable hashAlgorithms = Hashtable.Synchronized(new Hashtable());
33:
34: /// <summary>
35: /// Hashing a given string with SHA2.
36: /// </summary>
37: /// <param name="data">Data to hash</param>
38: /// <returns>Hashed data</returns>
39: public static string HashData(string data)
40: {
41: return HashData(data, HashType.SHA256);
42: }
43:
44: /// <summary>
45: /// Hashing a given string with any of the supported hash algorithms.
46: /// </summary>
47: /// <param name="data">Data to hash</param>
48: /// <param name="hashType">Hashing algorithm to use</param>
49: /// <returns>Hashed data</returns>
50: public static string HashData(string data, HashType hashType)
51: {
52: HashAlgorithm hash = GetHash(hashType);
53: byte[] bytes = (new UnicodeEncoding()).GetBytes(data);
54: byte[] hashed = hash.ComputeHash(bytes);
55: StringBuilder sb = new StringBuilder(64);
56: foreach (byte b in hashed)
57: sb.AppendFormat("{0:x2}", b);
58: return sb.ToString();
59: }
60:  
61: private static HashAlgorithm GetHash(HashType hashType)
62: {
63: if (!hashAlgorithms.ContainsKey(hashType))
64: hashAlgorithms.Add(hashType, CreateaHashAlgorithm(hashType));
65: return hashAlgorithms[hashType] as HashAlgorithm;
66: }
67:  
68: private static HashAlgorithm CreateaHashAlgorithm(HashType hashType)
69: {
70: switch (hashType)
71: {
72: case HashType.MD5:
73: return new MD5CryptoServiceProvider();
74: case HashType.SHA1:
75: return new SHA1Managed();
76: case HashType.SHA256:
77: return new SHA256Managed();
78: case HashType.SHA384:
79: return new SHA384Managed();
80: case HashType.SHA512:
81: return new SHA512Managed();
82: default:
83: throw new NotImplementedException();
84: }
85: }
86: }
87:  
88: public enum HashType
89: {
90: MD5,
91: SHA1,
92: SHA256,
93: SHA384,
94: SHA512
95: }
96: }

 

Not beautiful, however useful.

 

You can download this file from here (just remove the .txt - the server doesn't serve .cs files directly)

 

btw, the colouring of the source was made with the help of http://www.manoli.net/csharpformat/, even though I had to do some manual tweaking to make it work with this blog. If colours of reserved words, comments etc. do not appear, then please refresh your browser's cache to get the updated css

2008 Jun 20

The Fox Is Hungry

tagged as: tools

My impression on Firefox 3 by now:

  1. It looks nicer.
  2. It still eats up all of my poor machine's memory

The fox is hungry

2008 Jun 18

Download Firefox 3

tagged as: tools

 

I really don't need to add anything, right?

 

download-button-primary

 

 

 

Installed it myself today. Appear to be a bit faster, and to eat up less memory.

 

The Google Toolbar and FireFTP were updated automatically.

 

I needed to manually re-install FireBug and IE-Tab

 

btw, does anybody know where did the Back and Forward buttons has gone to? Im using the keyboard usually, but sometimes (especially during in-office-lunch-time) I need to click the Back thing with the mouse

 

UPDATE: it appear that as part of the upgrade, FF3 has inherited my customised toolbars and that's why it was looking weird.  So I right-clicked on the toolbar -> customise, the clicked "Restore Default Set". All the buttons came back, then I rearranged the toolbar to my liking.

2008 Apr 3

Logging SQL output from NHibernate, using Log4Net

tagged as: tools | nhibernate

Following a question from NHibernate's users list:

<configSections>
  <section name="log4net"
            type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
 
<log4net>
  <appender name="rollingFile"
            type="log4net.Appender.RollingFileAppender,log4net" >
    <param name="File" value="log.txt" />
    <param name="AppendToFile" value="true" />
    <param name="DatePattern" value="yyyy.MM.dd" />
    <layout type="log4net.Layout.PatternLayout,log4net">
      <conversionPattern value="%d %p %m%n" />
    </layout>
  </appender>
  <logger name="NHibernate.SQL">
    <level value="ALL" />
<appender-ref ref="rollingFile" />
</logger>
</log4net>

and configuring your application to use Log4Net (if you hadn't done that anyway):

 

log4net.Config.XmlConfigurator.Configure();

 

If you wan't to know more about log4net and it's configuration options - look here or use your favorite search engine.

2008 Mar 9

AgentSmith - Resharper plugin

tagged as: visual studio | c# | tools

From the website:

Current version includes following features:

  • Naming convention validation.

  • XML comment validation.

  • XML comment, string literals, identifiers and resources (.resx files) spell checking

  • Smart paste.

The coolest thing is the ability to spell check identifiers. I'd love it.

 

It's at http://www.agentsmithplugin.com/ and I found out about it on Castle's dev list (thx Victor)

2008 Mar 4

[Tool] - Visual XPath

tagged as: tools

As I'm trying to avoid xml files as much as possible, when I do find the need to xpath, I always need to refresh my memory on the matter.

 

Today I've been working with kml files, and the need for some simple xpath queries came up, forcing me to do some trial-and-error in an area I don't really like ...

 

Next time I'll have Visual XPath to help me with that.

2008 Jan 27

Already Added Stuff To SQL Query Generator

tagged as: tools | SQL Server

the new stuff:

  • Reusing clauses
  • Operators (||, &&, !) on where clause
  • OrderBy clause

Examples:

Reusing clauses:

FromClause from = new FromClause(SQL.Blogs);
WhereClause where = new WhereClause(SQL.Blogs.Id == 2);
SQLQuery q1 = SQLQuery
    .Select(SQL.Blogs.Id)
    .From(from)
    .Where(where);
SQLQuery q2 = SQLQuery
    .Select(SQL.Blogs.Name)
    .From(from)
    .Where(where);
Console.WriteLine(q1);
Console.WriteLine(q2);

makes

SELECT
                [dbo].[Blogs].[Id]
FROM
                [dbo].[Blogs]
WHERE
                ([dbo].[Blogs].[Id] = 2)
SELECT
                [dbo].[Blogs].[Name]
FROM
                [dbo].[Blogs]
WHERE
                ([dbo].[Blogs].[Id] = 2)

 

 

Operators:

SQLQuery q1 = SQLQuery
                .Select(SQL.Blogs.Id)
                .From(SQL.Blogs)
                .Where(SQL.Blogs.Id > 2 || SQL.Blogs.Name == "Ken");
Console.WriteLine(q1);

makes

SELECT
                [dbo].[Blogs].[Id]
FROM
                [dbo].[Blogs]
WHERE
                (([dbo].[Blogs].[Id] > 2) OR ([dbo].[Blogs].[Name] = N'Ken'))

 

 

OrderBy Clause:

SQLQuery q = SQLQuery
    .Select(SQL.Blogs.Id)
    .From(SQL.Blogs)
    .Where(SQL.Blogs.Id > 2)
    .OrderBy(Order.By(SQL.Blogs.Id), Order.By(SQL.Blogs.Name).Desc);
Console.WriteLine(q);

 

makes

SELECT
                [dbo].[Blogs].[Id]
FROM
                [dbo].[Blogs]
WHERE
                ([dbo].[Blogs].[Id] > 2)
ORDER BY
                [dbo].[Blogs].[Id],
                [dbo].[Blogs].[Name] DESC

 

Didn't have time to upload a binary, but you can simply grab the source and build yourself. it has absolutely no dependencies but .NET 2.0

Where from?

http://svn.castleproject.org:8080/svn/castlecontrib/Castle.Tools.SQLQueryGenerator/trunk/

UPDATE (22/06/2008):
The source has slightly moved (to a sub folder):
http://svn.castleproject.org:8080/svn/castlecontrib/Tools/Castle.Tools.SQLQueryGenerator/

2008 Jan 27

SQL Query Generator - First Release

tagged as: tools | SQL Server
What is it?

A tool that generates a strongly typed representation of a relational database, to be used for generating SQL queries in a type-safe fashion, with the aid of intellisense.

 

Where to get it?

 

Limitations:
  • Currently works only with SQL Server 2005. Patches for more DB types would be welcomed.
  • Currently only SELECT queries are implemented. Soon I'll add support for generating INSERT, UPDATE and DELETE, too.
  • GroupBy, Order By and Having clauses didn't make it to this initial release. I hope to add those this week.
How to use it?
  1. Generating the classes:
    Run Castle.Tools.SQLQueryGenerator.exe.
    Parameters:
    The mandatory flag is /db:DBNAME where DBNAME is your database name.
    By default, the server being looked for is (local). you can select another using /server:SERVER.
    By default, Integrated Security is used. You can supply /userid:USER and /password:PASS to override it.
    You can alternatively supply a /connectionstring:CONSTR parameter.
  2. Add the generated file, named "SQLQuery.Generated.cs" to your project.
  3. Add a reference to Castle.Tools.SQLQueryGenerator.Runtime.dll
  4. Use and Enjoy

Usage sample (from Examples.cs in the test project:

SQLQuery q = SQLQuery
    .Select(SQL.Blogs.Id, SQL.Blogs.Name)
    .From(SQL.Blogs);
Console.WriteLine(q);

Would print out:

SELECT
                [dbo].[Blogs].[Id],
                [dbo].[Blogs].[Name]
FROM
                [dbo].[Blogs]

 

Not impressed? Well,

dbo_ForumMessages Message = SQL.ForumMessages.As("Message");
dbo_ForumMessages Parent = SQL.ForumMessages.As("Parent");
SQLQuery q = SQLQuery
    .Select(Message.Id, Message.ParentId, Message.Content)
    .From(Message)
        .Join(Parent, Message.ParentId == Parent.Id);
Console.WriteLine(q);

Will spit out

SELECT
                [Message].[Id],
                [Message].[ParentId],
                [Message].[Content]
FROM
                [dbo].[ForumMessages] AS [Message]
    JOIN        [dbo].[ForumMessages] AS [Parent] ON
                    ([Message].[ParentId] = [Parent].[Id])

 

Need parameters?

Parameter<int> blogId = new Parameter<int>("BlogId"); 
SQLQuery q = SQLQuery
    .Select(SQL.Blogs.Id, SQL.Blogs.Name)
    .From(SQL.Blogs)
    .Where(SQL.Blogs.Id == blogId);
Console.WriteLine(q);

would echo

SELECT
                [dbo].[Blogs].[Id],
                [dbo].[Blogs].[Name]
FROM
                [dbo].[Blogs]
WHERE
                ([dbo].[Blogs].[Id] = @BlogId)

 

How can YOU help?
  1. Use it. Praise it. Use Paypal.
  2. Or you can suggest improvements, spot bugs, create patches and buy me beer.
2008 Jan 19

Retrieving All Column Names And Types From SQL Server 2005 For .NET

tagged as: tools | SQL Server

Nothing fancy.

With a little help from Moran Benisty, here's the script I use to get the metadata I need for the SQLQueryGenerator:

 

SELECT   schemas.name AS [Schema],
         tables.name AS [Table],
         columns.name AS [Column],
         CASE
             WHEN columns.system_type_id = 34    THEN 'byte[]'
             WHEN columns.system_type_id = 35    THEN 'string'
             WHEN columns.system_type_id = 36    THEN 'System.Guid'
             WHEN columns.system_type_id = 48    THEN 'byte'
             WHEN columns.system_type_id = 52    THEN 'short'
             WHEN columns.system_type_id = 56    THEN 'int'
             WHEN columns.system_type_id = 58    THEN 'System.DateTime'
             WHEN columns.system_type_id = 59    THEN 'float'
             WHEN columns.system_type_id = 60    THEN 'decimal'
             WHEN columns.system_type_id = 61    THEN 'System.DateTime'
             WHEN columns.system_type_id = 62    THEN 'double'
             WHEN columns.system_type_id = 98    THEN 'object'
             WHEN columns.system_type_id = 99    THEN 'string'
             WHEN columns.system_type_id = 104   THEN 'bool'
             WHEN columns.system_type_id = 106   THEN 'decimal'
             WHEN columns.system_type_id = 108   THEN 'decimal'
             WHEN columns.system_type_id = 122   THEN 'decimal'
             WHEN columns.system_type_id = 127   THEN 'long'
             WHEN columns.system_type_id = 165   THEN 'byte[]'
             WHEN columns.system_type_id = 167   THEN 'string'
             WHEN columns.system_type_id = 173   THEN 'byte[]'
             WHEN columns.system_type_id = 175   THEN 'string'
             WHEN columns.system_type_id = 189   THEN 'long'
             WHEN columns.system_type_id = 231   THEN 'string'
             WHEN columns.system_type_id = 239   THEN 'string'
             WHEN columns.system_type_id = 241   THEN 'string'
             WHEN columns.system_type_id = 241   THEN 'string'
         END AS [Type],
         columns.is_nullable AS [Nullable]

FROM              sys.tables tables
    INNER JOIN    sys.schemas schemas ON (tables.schema_id = schemas.schema_id )
    INNER JOIN    sys.columns columns ON (columns.object_id = tables.object_id)
 

WHERE     tables.name <> 'sysdiagrams'
    AND   tables.name <> 'dtproperties'
ORDER BY [Schema], [Table], [Column], [Type]

 

Quick, Dirty, Working.

 

Anyone up to contributing a similar thing for SQL 2000 / MySql / Oracle / Postgres  / MS-ACCESS ?

 

it's going to be subversion-ed really soon.

2008 Jan 19

SQL Query Generator

tagged as: tools | SQL Server

Imagine you could write that in your IDE:

SQLQuery q = SQLQuery
    .Select(SQL.Blogs.Id, SQL.Blogs.Name)
    .From(SQL.Blogs)
        .Join(SQL.Posts, Join.On(SQL.Blogs.Id == SQL.Posts.BlogId))
    .Where(SQL.Blogs.Name != "Ken's blog");
Console.WriteLine(q);

and getting that output :

SELECT [Blogs].[Id], [Blogs].[Name]
FROM ([Blogs] JOIN [Posts] ON ([Blogs].[Id]=[Posts].[BlogId]))
WHERE ([Blogs].[Name]<>'Ken''s blog')

 

Soon enough you would be able to to that.

 

After having fun creating the Static Sitemap Generator, today I've had a little free time (as my main machine is being reinstalled), so I came up with a SQL query generator.

It would be a tool to generate classes out of a database, that would make writing typed sql queries a breeze.

 

I have most of it working, except the part where I retrieve the metadata from the database ... No worries, my good friend and SQL guru Moran is about to send me the queries for that real soon.

 

First release would work with SQL Server 2005, and later on I'll add extension points to hook up other db engines.

2008 Jan 17

YAGNI - My Tiny IoC Feels Lonely

tagged as: architecture | tools

It's funny. At the end of the day, I didn't use the tiny IoC in the StaticSiteMap for the testing.

It was fun however.

2008 Jan 17

StaticMapGenerator Source Is Available

tagged as: asp.net 2.0 | tools | castle

The Static SiteMap Generator's home is in Castle Contrib, and it's named Castle.Tools.StaticMapGenerator

 

I've just commited it to the repository, so it's at http://svn.castleproject.org:8080/svn/castlecontrib/Castle.Tools.StaticMapGenerator/trunk/

 

UPDATE (22/06/2008):
The source has slightly moved (to a sub folder):
http://svn.castleproject.org:8080/svn/castlecontrib/Tools/Castle.Tools.StaticMapGenerator/

 

I hope to have time soon to blog about the creation of this little tool, and of the usage. Also, expect a binary soon.

2008 Jan 17

StaticMapGenerator for ASP.NET, First Teaser

tagged as: asp.net 2.0 | tools | monorail

Last night I got frustrated with the fact that I have no intellisense (nor compile time check) for locating static files like .js, .css and image files.

So I sat up and created a simple console application that can generate exactly that, out of the site's filesystem.

 

usage:

D:\MyTools\StaticMapGenerator /site:D:\Dev\MySite

it generates a file called Static.Site.Generated.cs within the site's root folder, and then I go and include that file in my web project.

No I can do stuff like:

<script type="text/javascript" src="<%= Static.Site.Include.Scripts.myscript_js %>"> </script>
 
<link rel="stylesheet" href="<%= Static.Site.Include.CSS.master_css %>" />
 
<img alt="Ken Egozi" title="My Logo" src="<%= Static.Site.Include.Images.Logos.my_logo_png" />

 

How cool is that?

It works in every ASP.NET compatible web framework (MonoRail, ASP.NET MVC, even WebForms ...)

The only prequisite is .NET 2.0 runtime.

 

Sorry for keeping it out of reach for the moment. I need a little bit of time to setup a svn repository to make the source public (it would of course be BSD/Apache2/MIT thing) and to upload a binary. No promises given, I'll try to make it in the coming weekend, or even tonight, so stay tuned.

The code is somewhat naive, and certainly does not cover any edge cases, however it's enough to work cleanly on the largest project I'm currently involved in (Music Glue). Patches to make it more configurable and able to handle more edge cases would be gladly accepted once it's out.

 

One cool spot - as part of this, I have also implemented my tiny IoC container in 33 LoC.

2008 Jan 17

It's My Turn To Build An IoC Container In 15 Minutes and 33 Lines

tagged as: architecture | tools | castle

Last night I've built a nice new tool called StaticMapGenerator which is used to generate a typed static resources site-map for ASP.NET sites (works for MonoRail, ASP.NET MVC and even WebForms).

I'll blog about it on a separate post in details.

Since I didn't want any dependency (but .NET 2.0 runtime) for the generator and the generated code, I couldn't use Windsor to IoC. That calls for a hand rolled simple IoC implementation

Ayende has already done it in 15 lines, but I wanted also to automagically set dependencies and have a simpler registration model.

so I've quickly hacked together a configurable DI resolver (a.k.a. IoC container) in 15 Minutes and 33 Lines Of Code. Call me a sloppy-coder, call me whadever-ya-like. It just works.

static class IoC 
{
   static readonly IDictionary<Type, Type> types = new Dictionary<Type, Type>();
  
   public static void Register<TContract, TImplementation>()
   {
      types[typeof(TContract)] = typeof(TImplementation);
   }
  
   public static T Resolve<T>()
   {
      return (T)Resolve(typeof(T));
   }

  
   public static object Resolve(Type contract)
   {
      Type implementation = types[contract];
  
      ConstructorInfo constructor = implementation.GetConstructors()[0];
  
      ParameterInfo[] constructorParameters = constructor.GetParameters();
  
      if (constructorParameters.Length == 0)
         return Activator.CreateInstance(implementation);
  
      List<object> parameters = new List<object>(constructorParameters.Length);
  
      foreach (ParameterInfo parameterInfo in constructorParameters)
         parameters.Add(Resolve(parameterInfo.ParameterType));
  
      return constructor.Invoke(parameters.ToArray());
   }
}

Ok, I've cheated. You'd need using statements too, but you can see that I was generous enough with newlines ...

Usage:

Given those:

public interface IFileSystemAdapter { }
 
public class FileSystemAdapter : IFileSystemAdapter { }
 
public interface IBuildDirectoryStructureService { }
 
public class BuildDirectoryStructureService : IBuildDirectoryStructureService
{
   IFileSystemAdapter fileSystemAdapter;
   public BuildDirectoryStructureService(IFileSystemAdapter fileSystemAdapter)
   {
      this.fileSystemAdapter = fileSystemAdapter;
   } }

You can do that:

IoC.Register<IFileSystemAdapter, FileSystemAdapter>();
 
IoC.Register<IBuildDirectoryStructureService, BuildDirectoryStructureService>();
 
IBuildDirectoryStructureService service = IoC.Resolve<IBuildDirectoryStructureService>();
You need not worry about supplying the BuildDirectoryStructureService with an implementation for the service it depends on, but only to register an implementation for that service.
2008 Jan 12

Conditional Rendering, or I Do Not Want Analytics Code On Dev Machine

tagged as: tools | monorail | aspview

From time to time you'd want some of your markup rendered only on 'real' scenarios. For example, you wouldn't want google analytics to track visits you do on your dev machine. Sometime you'd even develop while your machine is not even connected to the internet, and every page would try get the analytics script and will behave strangely.

 

In Monorail, the Request has a property named IsLocal, just for that. I've wrapped it in a nice ViewComponent.

 

public class GoogleAnalyticsComponent : ViewComponent
{

    public override void Render()
    {
        if (Request.IsLocal)
            return;
        RenderView("AnalyticsCode");
    }
}

 

Accompanied by the AnalyticsCode view template:

<%@ Page Language="C#" Inherits="Castle.MonoRail.Views.AspView.ViewAtDesignTime" %>
<script src="https://ssl.google-analytics.com/urchin.js" type="text/javascript"></script>
<script type="text/javascript">
    _uacct = "MY_URCHIN_CODE";
    urchinTracker();
</script>

, that can easily be extensible to set the urchin code with a parameter.

2007 Dec 4

Cool vs Uncool in programming languages

tagged as: c# | tools

Have just read Ayende's post about C#/Java vs Boo/Ruby.

Tried to comment, but then I decided it's worth a post.

I'd say that the difference is MAF - Management Acceptance Factor

  • Java and C# has the Big Names behind them, so managers are comfortable. Ruby and Boo does not, hence ...
  • Java is v6, c# is v3, while Ruby and Boo are v0.x - another Management Scary.

Boo is also a way too cool/strange/creepy name for a distinguished suit to grasp.

It's like when you're a collage girl, and you want to introduce your new boyfriend to your mama. It doesn't matter that he has a BSc and MBA plus 3 castles in the Swiss alps. If he'd first show up to the family on his way-too-cool motorcycle, then you're going to be grounded.

 

When I approached my last manager about MonoRail, and told him that the views will be written in 'Boo', he got all scared. Then I wrote AspView, views to be written in c#, and he gave consent to go MonoRail.
Even though, at least at that time, Brail was way more mature than AspView.
The 'cooler' languages needs to be marketed to management.

Ruby works in Eclipse. I wonder who is going to start an OSS effort to create a decent Boo plugin for VS2008 (based on the VS2008 shell).

Make it demoable, make it look 'official', and MAF would go way higher.

2007 Nov 27

Using the CodeGenerator and the DictionaryAdapter

tagged as: tools | castle | monorail | aspview

Following users requests, I have just posted two documents to using.castleproject.org.

The first is an explanation about the CodeGenerator (from Contrib), and another one, on using the DictionaryAdapter.

Here are the links:

 

Related stuff:

2007 Nov 15

HOWTO: Make Windows Live Writer Output XHTML Markup

tagged as: miscellanea | tools

Problem:

  • The output you get from Windows Live Writer is not XHTML, i.e. unclosed br and img tags.

 

Possible causes:

  • When you've setup your blog in Windows Live Writer, you have used a version older than Beta 3
  • Your blog's style couldn't have been detected by WLW
  • Your blog's style was been detected correctly, however you do not have a valid XHTML DOCTYPE declaration in your blog

Setting XHTML output manually:

  • Weblogs | Edit Weblog Settings | Advanced | Markup Type

 

Thanks Mr. Joe Chang, from the Windows Live Writer team, who have pointed that out for me.

2007 Oct 8

AspView for Castle RC3 - new release

tagged as: tools | castle | monorail | aspview

Although about three weeks too late, I present thee:


AspView, built for Castle RC3 (release, debug, source)


I've also introduced a well due improvement to the engine. Now it supports the use of a 404 rescue view, that would get rendered in case of the url mapping to a non-existent controller.

 

the commit comment (for revision 314) says it all:

Handling view creation for EmptyController, specifically when a controller is not found and a 404 rescue exists

Next improvement will include an option for doing AutoRecompilation in memory, as sometimes the IIS process gets hold on the CompiledViews assembly files (dll and pdb) and failing the automatic recompilation process.

I certainly need that as it happens on my machine too much, and building the Web project takes a solid 10-15 seconds, while running vcompile is a milliseconds thing only.

 

Soon ...

2007 Oct 7

IE7 to the masses - the end of IE6 compatibility issues?

tagged as: client-side | css | tools

That's a great news for everyone who build websites and web applications.

IE7 would be installable even to XP users without the Genuine Check.

That means that in short time, the IE7 adoption rate would increase so much, that hopefully the annoying IE6 would become as obsolete as Netscape 4 and IE 5.5 ...

 

No more dirty CSS hacks (or at least, a lot less)

No more buggy box-model

Finally we can use input[type=text] and the likes

 

I've kept IE6 on my box for so long only to be able to test what I write. Even though I use Firefox for day-to-day browsing, I still need IE for some crappy israeli sites that would just not work on non IE (and by not work - I mean that you get an alert box saying:

This site is IE only

For people who knows not Hebrew:

"This site supports IE browsers, from version 5.5 and up. Support to other browsers is planned for next release"

Ha Ha.

This message is there for at least a year.

And it's not even dependant on ActiveX or other IE magic. It's only some laziness regarding JS and CSS compatibility.

2007 Sep 21

Yet Another xUnit framework for .NET

tagged as: tools

look at http://www.codeplex.com/xunit

Quite interesting. I might give that a shot soon.

You can read about it at http://jamesnewkirk.typepad.com/posts/2007/09/announcing-xuni.html

The upside for that is the simplification of things by removing some attributes, and having a more consistent model regarding assertions on exceptions.

2007 Sep 12

I'm Burned

tagged as: tools

Main reason - I want to reduce traffic to my blog (I do have a gazzilion a million few hundreds subscribers, just like you, my dear reader.).

Plus, since feed-burner has gone Google-d, they give the PRO services for free, so I'd be able to enjoy the stats - which means I'd be able to know exactly how many people are reading me, and then can arrange the kenegozi-readers-party (thought about the Madison Square Garden, but I guess my living room will do just fine).

 

So, please update your favorite reader to point to http://feeds.feedburner.com/kenegozi.

2007 Sep 11

Google Reader Is Even Better - They've Added a Search Box

tagged as: tools

Seriously, it's Google. What took them so long?

 

Anyway - Google Reader remains my feed reader of choice. I do not use my laptop offline much, so it's ok like that, plus the offline mode in reader kinda works, so for the occasional offline sessions I do have it's more than enough.

 

It took me almost a week to notice, though ...

2007 Aug 27

VS2005 has lost grip of Resharper 3 Fonts and Color? re-install

tagged as: visual studio 2005 | tools

I'm using VS2005 (with SP1, like duhh) and have had R# 3.0.1

Now, I'm not a fan of the default font and color scheme, as I like better the slicker mono-fonts, like Consolas. I am also becoming a Black-Background type, not for the WouldSaveTheRainForests==true reason (in LCD the light is static no matter what color it shows) but for the  implements IDLikeToKeepMyEyeSightForALongTime reason.

So, started with importing a color scheme from some internet-found-place, don't remember where, and then tried to change those Resharper coloring options (like, a variable name that is being used an odd amount of times, by internal classes, however not in an explicit-interface implemented method, that returns a struct), just to find out the the Fonts-And-Colors menu miss those lovely Resharper entries).

Okay, so what should I do? Export the settings, edit the xml, and re-import.  Not much fun there.

Hmm. Googled it (I may use the term, as I actually use Google as a search engine), and found a post on jetbrains support site, with the same problem.
no solution though.

However - this is how I solved it eventually:

1. Export the current settings to a file

2. Reset all settings

3. Re-install R# (hey - now it's 3.0.2 !!)

4. Import back my settings.

2007 Jul 30

Merging with TortoiseSVN

tagged as: tools

Assuming you have a main "trunk" in your subversion repository, and that you are actually working on a different branch.

You'd need to merge your changes from your branch to the trunk so other team members would be able to use your code. You'd also want to be able to merge from the trunk to your branch, to be able to use your teammate's code.

The thing you should bear in mind while you merge, is that the actual merge process is actually working by generating a patch (using diff) and applying this patch on the target.

a quick note: It is very much recommended that you have committed all changes to the target of the merge, into the repository, so it would be easy to revert if something went wrong.

So:

Merging from a branch to the trunk

a. Go to the trunk folder on your filesystem, right-click->tortoise->merge.

b. You want the changes between the current trunk revision and your branch's current revision to be applied on the trunk, so you choose:
From: your trunk, revision HEAD
To: your branch, revision HEAD.

I know, the terminology is confusing, as you want to "update" from the trunk to the branch's state, but remember that you want the diff(erence), or in other words, the changes that will take the trunk FROM it's current state, TO your branch's state.

screenshot:

 branch to trunk

now you have a merged trunk on your workstation. Make sure that everything compiles and that tests are green, and commit.

Merging from the trunk to a branch

a) Go to your branch's folder, right-click->tortoise->merge;

Now, you want the changes between the last trunk revision that you have on your branch, to the newest revision of the trunk. To find out that last trunk revision that you have on your branch, go to your branch's folder, right-click->tortoise->show-log, and look for it. If you are a good reader you'd easily find it since you have mentioned the revision numbers of your merges in the commit remarks, as you are kindly recommended)
A screenshot from the branch's log:

Branch log

I need to check if I have merged my branch to the trunk on a later point. I'll do that using the Trunk's log (trunk folder, right-click->tortoise->show-log):

Trunk Log

Indeed. It seams that my branch is in sync with the trunk at revision 918

b) Now you fill
From: your trunk, revision "last revision you have"
To: your trunk, revision "new, wanted state" (usually HEAD).
in my example, the last trunk version I have merged into my branch is 902, so that's the screenshot:

trunk to branch

I know, terminology sucks again. You probably thing "from trunk to trunk? Is he crazy?" well, again, you want to get the changes that was made TO THE TRUNK, and apply them to your branch. Remembering that this is actually a patch that will get applied make anything clear again.

now you have a merged branch on your workstation. Make sure that everything compiles and that tests are green, and commit.
Recommendation: write down in the commit's remark, the revision number of the trunk (the current HEAD before the merge) for next time.

My thanks to this page, and to Lee Henson who have pointed it out for me, and helped my grasp the whole merge==diff'n'patch thing.

2007 Jul 28

A Sign That I'm Starting To Like NHQG Too Much

tagged as: tools | nhibernate

Today I noticed that piece of code on my working copy:

Repository.Blog.FindOne(Where.Blog.Id == blogId)
2007 Jun 24

Regionerate - c# region maker

tagged as: tools | castle | activerecord | monorail

Check out this nice tool from Omer Rauchwerger.

 

It could help a team to manage a coding convention. Should be very useful in Open Source environments. For example, when committing changes to castle project (or sending a patch) there is a coding standard than needs to be followed. Regionerate could help a lot with that effort.

 

I need to see if it can select methods and properties by attributes. It could then help making MonoRail controllers and ActiveRecord decorated classes more readable (region of all actions with a "SkipFilterAttribute", region of "Property" and region of "HasMany", etc.)

 

UPDATE:

Silly me, I forgot to mention that I found about this great tool at Roy Osherov's blog. A very good one, that is. Many Agile related stuff, and funny little things, too. So go on and subscribe to it's feed.

2007 Jun 22

VS 2008 Javascript Intellisense + PrototypeJs => isFunToScriptBrowsers == true

Checkout the latest post of Scott Guthrie.

Is the long awaited JS IDE will be VS2008?

Now it's a matter of adding ///<summery> tags to prototype.js and maybe people would really stop being afraid of developing javascript code.

Now that's a good reason to switch to VS2008, combined with the fact than you can hold to your current .NET distribution.

2007 Jun 20

Visual Studio 2008 will target multiple .NET runtimes

tagged as: visual studio | tools

That's a big announcement.

After all, even VS2005 was actually calling csc.exe rather that calling some magical inner stuff as in 2002/2003.

I hope that this also means better addin development support, so great projects like CVSI and ActiveWriter, could become even better.

Do you think they'd enable a "Compile for Mono" option?

2007 Jun 15

AspView - a little bugfix

tagged as: tools | castle | monorail | aspview

If you are an AspView user you might have noticed a problem.

If you setup a nullable-value-type parameter with a default value other than null, then you'd get a casting error.

 

example:

<%
    int? someInt = default(int);
%>
some markup 
<% if (someInt == default(int)) DoSomething();%>

 

it happened because of the way GetParameter worked

GetParameter is a method that gets a view parameter value from the view's properties collection (PropertyBag, Flash, Request.Params, etc.). It's located in the AspViewBase class (the base class for each and every view in the AspView world).

 

So, now it's fixed, and a test was added to make sure it'll stay that way.

 

As soon as google.com will be accesible again, you'd be able to check out and build.

UPDATE:

I'm too tired (3am here). The sources are on castle contrib and not on google, so you'd find them here

2007 May 31

Google Gears - Local storage and Offline mode for Rich Internet Application

tagged as: client-side | tools

Wow.

Another great tool from Google.

 

http://gears.google.com/

 

Works on Win/Mac/Linux, for IE and FF.

 

In a few words - it can give you offline browsing, plus local storage using SQLite (so you can run SQL queries strait from your javascript to query the local store)

 

I wonder what secutiry issues can come up. However, it looks very cool, and can help bring power to existing DHTML/Ajax apps.

 

Makes me think. Now that you do SQL from javascript, isn't it time for JsHibernate? and what about an ActiveRecord inplementation in javascript?

 

So, in the Flex/Silverlight war, it seams that Google is gonna win again ...

 

(from Scott Hanselman's Blog)

2007 May 30

NANT 0.85 rc3 and .NET 2.0

tagged as: tools | castle | monorail

I needed to manually Castle today, for the first time.

The need is for Castle.MonoRail.TestSupport.BaseControllerTest only, so I do not really care about all the rest.

 

Opened "How to build.txt"

I know that the builds in the CI server are failing due to some filing tests on DP2, so I add "-D:common.run-tests=false".

no brainer.

I am also targeting .net2 only, so I add "-t:net-2.0"

baboom. This fails.

The nant exe is telling me that I can only build to .net 1.1, or .net compact framework 1.0.

So I went to nant's config file, and found out to my surprise, that the frameworks that are present there are:

.net 1.1,

.net compact framework 1.0

.net 2.0 BETA 1

hmmm.

So I've edited the config, changed the existing .net 2.0 config name to .net2.0Beta1,

copy&pasted the .net node to another one, now switching version number from

sdkdirectory="${path::combine(sdkInstallRoot, 'bin')}"
frameworkdirectory="${path::combine(installRoot, 'v2.0.40607')}"
frameworkassemblydirectory="${path::combine(installRoot, 'v2.0.40607')}"
clrversion="2.0.40607"

to

sdkdirectory="${path::combine(sdkInstallRoot, 'bin')}"
frameworkdirectory="${path::combine(installRoot, 'v2.0.50727')}"
frameworkassemblydirectory="${path::combine(installRoot, 'v2.0.50727')}"
clrversion="2.0.50727"

 

voila. Now the build is starting.

However, the Castle.Components.Validator.Tests dll refuse to build. I'll disable it, too.

 

UPDATE:

I'm an idiot. Did not notice that NAnt has gone far beyond rc3 a long time ago ...

2007 May 27

New feature to the blog - a blogroll

just added a blogroll.

To the DB, to the Domain, to the controller and to the view.

Took me (all in all) 30 minutes, including all the coding, CSS-ing, uploading to the webserver, setting up the DB table on the hosted server, adding a few entries, clearing the browser's cache, and viewing it.

ah, and committing changes to Google code.

 

All of that was made in the Budapest Airport cafeteria, while waiting for my flight home (was a great trip. Photos, though not many of them, will be posted later on).

 

Rest assure that the DB access code is tested, and that the calls to the DB and to the cached data from the Controller and View are all typed.

 

I'd like to thank NHibernate, Castle and AspView (hey - that's me !), who made this possible.

 

I bet Ayende would have done it in 20 ...

2007 May 25

Things my blog is missing

tagged as: tools | aspview | personal | blog engine

Since this blog is running on an engine that I wrote (available on Google code site, here), it lack some features that more mature blog engines already have. (the other engines lacks the combined power of ActiveRecord/MonoRail/AspView ...)

 

So, that's currently my list:

1. Blogroll, for obvious reasons.

2. Email alert for me when anyone posts a comment for one of my posts.

3. Comments feed (via ATOM).

UPDATE - Done

4. Email subscriptions for new posts, or new comments on specific posts.

5. I have a problem with the font. I should fix the CSS but the Internet connection here (I'm at a Budapest hotel) is quite poor. Will be fixed next week.

UPDATE - Done

 

Any other suggestions?

 

note that I do not intent on implementing Pingbacks and Trackbacks, since those were littering my blog in the past.

2007 May 24

NUnit.org seams down

tagged as: tools

So if you wanna download it, you should go directry to the NUnit's page on sourceforge

2007 May 20

A new version of AspView - 0.7

tagged as: asp.net 2.0 | tools | castle | monorail | aspview

I've just commited to the repository a new version of AspView.

The main addition is "Auto Recompilation" feature.

This means that when you change one of the view sources, the application will automatically recompile the views upon the following request.

 

You enable the feature by adding the next attribure to the aspview config section in web.config:

 

<aspview ....  autoRecompilation="true" ... > ... </aspview>

 

Breaking change:

If you happen to reference an assembly from the GAC (using the aspview configuration in the web.config) you need to add a hint for the engine, like this:

<reference assembly="MyAssemblyFromGAC.dll" isFromGac="true" />

 

Known issues:

1. You need to let ASPNET user (or the Application Pool user) a modify access on the bin folder.
Note that if you use the inner WebServer of Visual Studio this should not be a problem, since in that case the web application runs with your user, that has the needed peremissions on th