Sean Feldman's profileברוכים הבאיםPhotosBlogLists Tools Help

Blog


    25/01/2008

    Don't Be A Slave Of Visual Studio & Don't Workship File System

    Understanding what are you working on is the priority #1. If you not sure, then you don't know what are you working on. How do you keep several items linked logically while working on them - you try to keep something common between them. To be more particular, I will bring an example of an application I was exposed to with my team, and show several approaches, including the one I am so against.

    The application has several sections. Each section has its' views. All the views are a part of the MVP pattern. One of the sections is called Product Management, where you can list all Product Releases in the system for a given Product, or create a new Product Release, or update an existing one. First image will show how the section file structure looks like.

    Note: the team is using R# and is trying to be compliant as much as possible to all its' requirements (such as folder structure should be driving the namespaces, etc).

    image

     

    First thing first. ProductManage - sounds good, but DM? As I learned it was an abbreviation of "Domain Model" - but wait a minute, there's view and presenter exist in that same folder as well, so it's no longer just DM.

    IViewEdit - bad. Not only it twist the logical naming of the class, but also copies the name of a different contract that belongs to a different section... and only because they partitioned by folders, they do not collide in name. They don't? Yes they do! When you work on those, you want to know what view contract is that. Not mentioning the inverted logic naming convention (IViewEdit, ViewEdit, IModelProduct, ModelProduct, DtoProduct, etc. - Long live Hungarian notation?!). After a few months a name like IProductReleaseEditView will ring a bell faster than IViewEdit, and then digging in what folder/sub-folder it lives in.

    To myself this is a slavery to VS.NET and file system.  Rather than trying to arrange all views, models, presenters nicely in a solution window, we should care about meaningful names classes/interfaces are given. Besides, R# is not looking for the file name, it is looking for the class/interface name on a search. And I would definitely put more trust in re-factoring tool, rather than in file editor... but these are personal preferences.

    16/01/2008

    Web Application Project Compilation And NAnt

    I am working on automated builds for our projects. I am quite excited about it, since it feels like taking back the power over the creation of the code. Not only that, the 'auto-magic' dissolves ones you do it manually and things become simple. You run the script, the script is failing, you need to fix the issue and you want the issue to be simple in order to A) locate it quickly B) fix in the least effort applied.

    Saying that, I have to admit that having a strong build scripts takes time to develop as well. Thanks to the (NAnt/NAntContrib) community this is not a difficult task even for a novice like myself. And lets get back to the concept - simplicity.

    If you look around, lots of build scripts are a single file that is doing it. But isn't this a sort of violation of SRP? One of the projects' build file in the entire solution should not be too overwhelming to read just because there's a bunch of projects and global properties. So I decided to partition.

    In my case the partitioning is working great (master build file and child build files). Parent build file acts as a trigger for each individual project, invoking the right target.

    This is great even with the projects that have dependencies on other projects in solution. The old plain CSC is doing it all.

    Web Application Project (WAP) - an absolutely different creature. I failed to launch WAP compilation with aspnet_compiler. So I used msbuild to compile the web application project and trace what it was doing. To my surprise it leveraged csc.exe compiler to do the job. When the web application was requested in browse, the aspnet_compiler kicked in. So does that mean there is no need in aspnet_compiler to compile a web site?

    PS: I will make a separate entry on Partitioned build files.

    Update: please read my comment below. I have found a temporary (and maybe a permanent) way to achieve the goal with WAP compilation.

    Edgile

    Combining client-side with server-side, coping with multi-browser support, handling imperfect world of CSS , implementing the code the best way you can relaying on patterns and principles with legacy code kicking around, keeping up with the pace of changing, facing clients that are not ready to pay for the quality, dealing with team mates that are still loyal to procedural code order and married to databases, yet not over-designing is more than just agile. My definition of this is going on the edge with agility in mind. Or just Edgility.

    14/01/2008

    Excellent Reading

    Just finished reading Agile Principles, Patterns, and Practices in C# from Robert and Micah Fowler Martin. A definitely recommended book. Some stuff is not taking advantage of the .NET (not using generics where could do that, Visitor pattern for example.

    Next book - Domain-Driven Design: Tackling Complexity in the Heart of Software. What else would you recommend that would fall into this category?

    03/01/2008

    NAnt And Visual Studio - Reporting From the Field Trip

    In my previous blog I was looking how to enable MbUnit with MSBuild from visual studio. As nice as it is, I was missing the flexibility and options of going beyond unit testing only.

    After attending "Nothing But .NET" training session help by JP Boodhoo in Calgary, I was more aware about option of using NAnt and CruiseControl.NET in the future for potential Continuous Integration.

    So why NAnt? Several reasons:

    • I was exposed to NAnt first
    • Simple XML like syntax that makes total sense
    • Lots of resources available from the OSS community

    As a beginner the first task was to make it work. Downloading the latest from the official site for NAnt, reading how-tos, and... not working. As a Visual Studio grown developer with addictions to Intelisense and mouse, I straggled to build a simple NAnt build file (script file interpretated by NAnt to perform tasks/operations) without copying it entirely from somewhere. Solution - keyboard can replace mouse, but Intelisense - nothing. Google has brought quiet a few results. What I loved in Kevin's solution was to teach Visual Studio about NAnt Intelisense using NAnt itself (nice idea!). What it does is basically dumps NAnt schema file into Visual Studio schemas repository folder. The great part about this approach is full automation of the process plus the ability regenerate the schema with updates, such ad NAntContrib (additional tasks that NAnt can do if you use it), in a painless way my 4 years old son could do. The simplified version looks like this:

    <target name="build-nant-schema-for-vs2005" depends="load-nantcontrib-schema" description="Generate VS intelisense for NAnt">
    <call target="load-nantcontrib-schema" />
    <nantschema output="NAnt.xsd" target-ns="http://nant.sourceforge.net/release/0.86-beta1/nant.xsd" />
    <property name="visual.studio.schemas.path" value="C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas"/>
    <copy todir="${visual.studio.schemas.path}" file="NAnt.xsd"/>
    <delete file="NAnt.xsd"/>
    </target>

     

    Well, I slightly re-factored Kevin's example to be partitioned better. So the target "load-nantcontrib-shema" is just another target (think of it as a sub-routine in NAnt script) to update normal NAnt schema with NAntContrib schema.

    <target name="load-nantcontrib-schema" description="Load NAntContrib tasks to generate schema">
    <property name="NAntContrib" value="C:\Data\SandBox\ProjectAbc\Tools\NAantContrib-0.85\bin" />
    <loadtasks assembly="${NAntContrib}\NAnt.Contrib.Tasks.dll" />
    <echo message="load-nantcontrib-schema finished." />
    </target>

    So now producing the Intelisense for Visual Studio (2005 in this case) as simple as executing a normal NAnt script:

    C:\Data\SandBox\ProjectAbc>nant load-nant-schema-for-vs2005

    This is making sure that any NAnt script file (also called build file) that contains reference to the schema has intelisense. A typical build file starts like this:

    <?xml version="1.0" encoding="utf-8" ?>
    <project name="Proxy" default="help"
    xmlns="http://nant.sourceforge.net/release/0.86-beta1/nant.xsd">

    What that default="help"? Help is one of the targets available in this NAnt script and if no target is provided in command line as an argument, the default is used, "help" in this case. I have picked this idea from the book that describes the NAnt in a very quick and practical way - Expert .NET Delivery Using NAnt and CruiseControl.NET. The idea is to have default target that will list all possible targets in script providing some help to people that did not build it, but have to use (the most important 'ility' - maintainability, isn't it?!)

    C:\Data\SandBox\ProjectAbc>nant
    NAnt 0.86 (Build 0.86.2898.0; beta1; 08/12/2007)
    Copyright (C) 2001-2007 Gerry Shaw
    http://nant.sourceforge.net

    Buildfile: file:///C:/Projects/Spikes/Proxy/default.build
    Target framework: Microsoft .NET Framework 3.5
    Target(s) specified: help


    help:

    [echo] Available Targets:
    [echo] build-nant-schema-for-
    vs2005
    [echo] clean
    [echo] build
    [echo] test
    [echo] run

    BUILD SUCCEEDED

    Total time: 0.1 seconds.

    Great. Now we need to pump the script contents and run it. But I am too lazy to leave the natural environment of inhabiting - Visual Studio. And even a cool tool like Console2 that is outstandingly great for this purpose, still doesn't make me feel like leaving the cave. So there's an add-in for Visual Studio 2005 called VSCmdShell (and 2008 according to authors, but never worked for me) that can give you the command shell as a part of Visual studio, where you can execute your NAnt build script with parameters (targets). Now editing, building and testing can be all done under one hood in peace and harmony - I heard hallelujah?.

    The next step - start building the targets to do cleaning, building, testing, and running. Deployment might be an option as well. I am in the beginning of my NAnt climbing curve, but it definitely looks great so far. Happy climbing!

     

    PS: I added a to demonstrate how VSCmdShell is playing nicely in VS.NET 2005 in combination with NAnt. My computer was about to die and Windows Media Encoder was not the best choice for encoder, but this is what I had, with this had to win :)

    Volta

    I was following the development on Script# CCC was developing. Sounded like an interesting idea of getting closer .NET and client-side JavaScript. Today found a link to MS experimental project called Volta (hmm, I wonder what will happen if you dare to touch it, same that happens to many experimental projects - a moment of joy and a big shocker at the end? :)

    NAnt And Visual Studio - Reporting From the Field Trip

    In my previous blog I was looking how to enable MbUnit with MSBuild from visual studio. As nice as it is, I was missing the flexibility and options of going beyond unit testing only.

    After attending "Nothing But .NET" training session help by JP Boodhoo in Calgary, I was more aware about option of using NAnt and CruiseControl.NET in the future for potential Continuous Integration.

    So why NAnt? Several reasons:

    • I was exposed to NAnt first
    • Simple XML like syntax that makes total sense
    • Lots of resources available from the OSS community

    As a beginner the first task was to make it work. Downloading the latest from the official site for NAnt, reading how-tos, and... not working. As a Visual Studio grown developer with addictions to Intelisense and mouse, I straggled to build a simple NAnt build file (script file interpretated by NAnt to perform tasks/operations) without copying it entirely from somewhere. Solution - keyboard can replace mouse, but Intelisense - nothing. Google has brought quiet a few results. What I loved in Kevin's solution was to teach Visual Studio about NAnt Intelisense using NAnt itself (nice idea!). What it does is basically dumps NAnt schema file into Visual Studio schemas repository folder. The great part about this approach is full automation of the process plus the ability regenerate the schema with updates, such ad NAntContrib (additional tasks that NAnt can do if you use it), in a painless way my 4 years old son could do. The simplified version looks like this:

    <target name="build-nant-schema-for-vs2005" depends="load-nantcontrib-schema" description="Generate VS intelisense for NAnt">
    <call target="load-nantcontrib-schema" />
    <nantschema output="NAnt.xsd" target-ns="http://nant.sourceforge.net/release/0.86-beta1/nant.xsd" />
    <property name="visual.studio.schemas.path" value="C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas"/>
    <copy todir="${visual.studio.schemas.path}" file="NAnt.xsd"/>
    <delete file="NAnt.xsd"/>
    </target>

     

    Well, I slightly re-factored Kevin's example to be partitioned better. So the target "load-nantcontrib-shema" is just another target (think of it as a sub-routine in NAnt script) to update normal NAnt schema with NAntContrib schema.

    <target name="load-nantcontrib-schema" description="Load NAntContrib tasks to generate schema">
    <property name="NAntContrib" value="C:\Data\SandBox\ProjectAbc\Tools\NAantContrib-0.85\bin" />
    <loadtasks assembly="${NAntContrib}\NAnt.Contrib.Tasks.dll" />
    <echo message="load-nantcontrib-schema finished." />
    </target>

    So now producing the Intelisense for Visual Studio (2005 in this case) as simple as executing a normal NAnt script:

    C:\Data\SandBox\ProjectAbc>nant load-nant-schema-for-vs2005

    This is making sure that any NAnt script file (also called build file) that contains reference to the schema has intelisense. A typical build file starts like this:

    <?xml version="1.0" encoding="utf-8" ?>
    <project name="Proxy" default="help"
    xmlns="http://nant.sourceforge.net/release/0.86-beta1/nant.xsd">

    What that default="help"? Help is one of the targets available in this NAnt script and if no target is provided in command line as an argument, the default is used, "help" in this case. I have picked this idea from the book that describes the NAnt in a very quick and practical way - Expert .NET Delivery Using NAnt and CruiseControl.NET. The idea is to have default target that will list all possible targets in script providing some help to people that did not build it, but have to use (the most important 'ility' - maintainability, isn't it?!)

    C:\Data\SandBox\ProjectAbc>nant
    NAnt 0.86 (Build 0.86.2898.0; beta1; 08/12/2007)
    Copyright (C) 2001-2007 Gerry Shaw
    http://nant.sourceforge.net

    Buildfile: file:///C:/Projects/Spikes/Proxy/default.build
    Target framework: Microsoft .NET Framework 3.5
    Target(s) specified: help


    help:

    [echo] Available Targets:
    [echo] build-nant-schema-for-
    vs2005
    [echo] clean
    [echo] build
    [echo] test
    [echo] run

    BUILD SUCCEEDED

    Total time: 0.1 seconds.

    Great. Now we need to pump the script contents and run it. But I am too lazy to leave the natural environment of inhabiting - Visual Studio. And even a cool tool like Console2 that is outstandingly great for this purpose, still doesn't make me feel like leaving the cave. So there's an add-in for Visual Studio 2005 called VSCmdShell (and 2008 according to authors, but never worked for me) that can give you the command shell as a part of Visual studio, where you can execute your NAnt build script with parameters (targets). Now editing, building and testing can be all done under one hood in peace and harmony - I heard hallelujah?.

    The next step - start building the targets to do cleaning, building, testing, and running. Deployment might be an option as well. I am in the beginning of my NAnt climbing curve, but it definitely looks great so far. Happy climbing!

    DRY or not?

    One of the web applications requirements is to provide a rich user experience. Client side validation and formatting is a part of this UX. The subject I want to address today is how to achieve a good level of UX on formatting with respect to one of the OO principles, DRY principle.

    The case is simple, user can edit multiple date inputs, that are reformatted right away. The screen would look like this:

    Item #1 delivery date:
    Sunday, 15/02/2008
    Item #2 delivery date:
    Monday, 16/02/2008
    ...  

    Where's the DRY issue is raising - formatting can be done on server side and on the client side. One of the requirements is to reformat the value right as it is entered. One of the options is to use Ajax - well, a suicidal option. Another one, to invoke some client side code (client presentation logic?) to do the formatting. But as soon as this is done, the logic is replicated on server and client. Or is it?

    The solution I go with is to have the logic centralized in a single location, execution of the logic done in different places. Having formatting rule in one location would allow to 'downsize' the replication of things. Formatting string identical to the one that .NET has will be passed to the client side code (JavaScript). That same code will leverage something like regular expression (or anything else that will assist reformatting).

    So how dry is that? Probably not the best solution, so what are your ways to solve this?

    Generating Changes

    This post is not going to be technical at all - pure theory of how to generate a change in minds of those who cannot accept what agility and test driven development are proposing.

    One of the biggest questions is "why". Why would someone bother to code to interfaces, if could deliver a working application without it. Why to have the hassle of creating test first, interface and then concrete implementation, going through enormous amount of code changes, if you can code the class, and in 'worse' case extract an interface 'just-in-case'? Why to give a method a fluent name and worry about simplicity, if you can 'dig the code to see what it's doing'? Why to bother test in isolation, if you can do the integration test. Hell, why even to bother doing integration, let the user do the testing...

    So I tried to step back, and rethink how to generate the change in minds, because once the mind is accepting the idea, techniques will definitely come after. One of the ideas I am trying to stick to is to serve an example (thanks JP for constantly reminding this) - let others see that you are standing behind your words and don't be afraid of admitting the fact that the learning curve for you has the same slope as for others.

    Keep challenging those that are in doubt - do not let them stay in the cozy spot thinking that since they won a single argue, they won the whole battle.

    Figure out the weak spots in the old school doctrine, and show how you can make it better.

    Experiment and benchmark - the best way to blow away assumptions is to show how they fail in reality. Get someone to read a procedural code of  a page and a half, or show how a call to stand-alone utility method fails the logic of an average developer to understand why there's a need to go to a utility that has no relationship to the subject at all.

    Give them the material for a thought. The true developer wants to know what's behind the door. If you leave the door slightly opened, the real developer will have a sneak look through it. And if so, then allow some time for ideas to be digested. It will grow in something bigger out of a curiosity. And if it won't, well, that was just a first level. The game is more appealing at the next one - keep trying!