May 1 2010

.NET 4.0 and Visual Studio 2010 Highlights

Category: ali @ 22:00

Well, VS.net 2010 has been released for at least two weeks now and you're probably thinking, "So what?!  My VS 2008 works just fine, why should I run out and upgrade just because Microsoft decided to release something?"

While working as an employee for large enterprises I felt EXACTLY the same way, as well I should have.  Late adoption makes sense in the enterprise because stability is key.  The focus of the organization is very likely not software innovation; it's making a profit through the business core competency.  Discarding a functional IT configuration in favor of the freshest available must be justified due to the cost of new licensing, user training and the explicit and latent costs of change.

Now as a principal in a small software development company the proposition is completely different.  Being a late adopter would mean that I don't care about being capable of delivering the best possible solution to my consulting clients.  Learning and using the best bits of the newest stack also make sense when considered from the software product development company perspective. 

Building a product to successfully compete in the cutthroat software product marketplace requires not only an agile, creative, talented, hard working team but also a technical edge.  The bottom line is that the cost of waiting is greater than the cost of adoption in our case.

Enough babble... time to drive you enterprise developers into a desire to learn the new bits in your free time and to whet the appetite of those of you who should be using this already.  Here are my favorite highlights of .NET 4.0 and compelling reasons to start using the new framework now.

  1. ASP.net MVC 2.0 has been around for a while now and can't really be considered a new feature but it has finally shipped as an activated feature with the release of Visual Studio 2010. 

    MVC deserves a series of blog entries all its own to cover just the basics and I can't possibly do it justice with an example of reasonable size here.  Instead, let me leave you with this thought regarding what you will find if you drink the kool-aid.  If you are a developer who likes to know what HTML, JavaScript and CSS your client browsers are actually seeing when they load your app and you sometimes worry about layers upon layers of generated code between you and the processor you will find MVC a breath of fresh air.  Put simply, it's smart, minimalist and extensible.

    Here are some good resources to get up to speed if you'd like to say goodbye to the if (!Page.IsPostBack) nonsense :
  2. Dynamic language elements are not something I've personally found a need for yet, probably because I've been using a static language for too long.  Regardless, it will be changing the C# landscape dramatically once this catches on.  At it's core think VB6 Late Binding reincarnate; type-related checking by the compiler is turned off for the dynamic type.  The interesting ramifications come with what you can do without the compiler slapping your hand:
    • Many talk of developing meta-languages (Domain-Specific Languages or DSLs) but I have to wonder if there's return on investment down that road?  Be the judge of DSLs for yourself.  There's nothing like a good hands-on example to try a concept on for size.

      Even if you don't delve into creating your own language it may still make sense to make segments of your codebase string-based and modifiable without recompilation.  IronPython and IronRuby will allow you to do just that and to pass data between C# and your string-based code.
    • Expando objects are objects that can have their definitions altered at runtime.  Imagine being able to write the code you're running with the currently running code.  Yes, ouroboros does spring to mind, but there are some interesting applications of this feature.  Python and Ruby need no longer be the envy of C#, at least not for being dynamic at runtime : )  Check out the Microsoft docs for the basics.
    The new Dynamic Language Runtime (DLR) docs from Microsoft and the docs regarding the new dynamic type are both good and concise.  They even have a good walkthrough of an example of how you might use dynamic.
  3. SQL Server Reporting Services has FINALLY released an update to their deployable runtime.  No more need to rely on the reporting services binaries that shipped with VS.net 2005 when doing local report rendering!  Time to upgrade those SSRS deployment packages.
  4. System.Threading.Tasks is reason enough to start using .net 4.0 now if you are developing with multiple threads.  Justin Etheridge has a good, brief overview on his blog.  Here's a simple usage example where multiple threads make perfect sense and can easily be implemented using the new Task object.  The ease with which we can now spawn asynchronous threads with StartNew and then join them back with WaitAll is a pleasure.  There are many options and use cases to explore to fit your problem at hand. This is a simple starting point. 
    using System.Threading;
    using System.Threading.Tasks;
    ...
            public void Sync(IRequestKey key) {
                HashDTO[] remoteHashes = null;
                HashDTO[] localHashes = null;
                Task t1 = Task.Factory.StartNew(() => {
                        remoteHashes = getRemoteHashes(key.Id);
                    });
                Task t2 = Task.Factory.StartNew(() => {
                        localHashes = getLocalHashes(key.Id);
                    });
                Task.WaitAll(t1, t2);
    	    // compare and process local and remote data here
    The Microsoft docs on the bigger picture of the concurrent processing plan and their docs on Tasks are worth a look.  The usefulness of the static Parallel class will probably lead to its becoming commonplace in short order.
  5. Optional and named method arguments seems like a "me too" feature but not so much after you stop to think about it.  Overloading is a great feature of object oriented programming, but what's even better is not having to write the overload at all.  Optional method parameters do for methods what property initializers did for constructors in .net 3.5.  Take this very simple, contrived example:
    // the best we can do with C# 3.5
    public List<dataitem> SimpleFind(string nameCriteria) { 
      // logic goes here, specific to just the name 
    }
    public List<dataitem> SimpleFind(string nameCriteria, int? ageCriteria) { 
      // logic goes here for both name and age 
    }
    
    // what we can do now with 4.0
    public List<dataitem> SimpleFind(string nameCriteria = "", int? ageCriteria = null) { 
      // logic inspecting parameters passed goes here 
    }
    The optional parameters are identified simply by having a default value specified with the = sign. It's not a revelation but writing less code to do the same job is always a welcome change of events to me.  Of course, you could have always passed a null or default value to a method similar to the second in the sequence but SimpleFind("", null) just doesn't compare to SimpleFind() for readability. 

    Named parameters are used on the other side of a method call to specify the parameters being passed. It's obviously superfluous under normal operations but this comes in handy when passing only a couple of optional parameters to a method that has several to choose from, as in the below.  As you can see all you need to do is prefix your parameter value with the parameter name and a colon. wordAutomation
  6. ClientIDMode is an overdue feature for ASP.net webforms.  How many times have you found yourself needing to muck up your otherwise elegant Javascript with something nasty like the below simply because ASP.net webforms insists on mangling control names when it renders HTML?
    function SomeInterestingJsFunction() {
        var controlRef = $('#<%=txt.ClientID%>');
        // this is where you interact with your asp.net generated control in js
        ...
    }
    The good news is that now you can choose to specify how ASP.net webforms generates its ID tags. We now have static, predictable, autoid and inherit. AutoID is the default and tells ASP.net to generate IDs the same as it's always been, the rest are all new. The most interesting (in my opinion) is static as it allows us to tell ASP.net to make the names we give our controls their HTML IDs.  Check the MSDN overview for more details or a related MSDN article about accessing ASP.net controls from js.
  7. Tuples are a brand new feature that at first glance seems like maybe a bad idea.  One definition of a tuple is an anonymous, immutable record type that you can pass between methods.  Yeah, it does sound messy, doesn't it?  On the one hand how much trouble is it really just to create a class with a few named properties rather than passing a tuple, but on the other hand if you consider how many data passing classes you normally create in a solution and then realize that coding most of them are now completely unnecessary...
            public List<Tuple<DateTime, decimal, char, int>> GetRecords() {
                Random rnd = new Random();
                var result = new List<Tuple<DateTime, decimal, char, int>>();
                for (int i = 1; i <= 100; i++)
                    result.Add(
    // the static Create method uses type inference to create an anonymous type with strongly typed fields
                        Tuple.Create(new DateTime(2010, rnd.Next(1,13), rnd.Next(1,29)),  
                            (decimal)rnd.Next(50, 500), 
                            (char)rnd.Next(65,91),
                            rnd.Next(1,101)));
                return result;
            }
    Apart from the potential reduction in the number of dto classes you need to code by hand, tuples also make functional currying techniques slightly more accessible from C#.  Currying a function enables you to do partial application of a that function by passing fewer arguments than it originally expected.  The result of the incomplete call is a state in which the remaining evaluation is "waiting" for additional arguments to be provided.

    What's that?  You're saying "Why would we entertain this craziness and how does it relate to the code I need to write?"  Two benefits that I can see are promoting broader function reuse and the methodology of solving complex problems through iterative functional complexity.  Passing a simple function to a simple function to a simple function allows for reuse of 3 functions as opposed to the single function resulting from the creation of a single context-specific function that expects all required arguments.

    Now you're probably wondering how this relates to tuples...  Tuples allow you to easily pass more complex data between your curried functions to solve real world problems.  Matthew Cochran has a good example of what currying looks like in C# and this post does a good job of explaining things from the ground up.  WARNING - this last reference is in F#, speaking of which...
  8. F# is Microsoft's showcase functional language and while it's been out there for a few years it is now finally a first class citizen with the VS.net 2010 release.  Lambdas and property initializers are elements of functional programming creeping into C# - so when programming functionally why not go full bore and use an F# project?  It will warp your mind a bit (it does mine), but it's probably time we all add F# to our coding arsenals.  Start here and the language reference is a good next stop. I am definitely a newbie on this front. I think of F# like the medicine I should be taking but don't have time to go to the pharmacy to get a refill. Like anything else the use it or lose it rule applies...
  9. The last feature (and deservedly least in this list) is the inclusion of a chart control for ASP.net webforms.  While the Microsoft chart control was available for download under 3.5 it's now "in the box".  The Microsoft docs leave something to be desired but the 4guysfromrolla site has a good article on the ins and outs. If you'd rather just see a snippet to get the gist here you go; with a tuple to make it interesting.  Databinding is no problem as you can see. For complete flexibility there is also a Points collection that can be specified.  The plethora of chart types implemented makes this addition to the toolkit pretty valuable.
    // the control definition in the aspx...
            <asp:Chart ID="Chart1" runat="server" Width="658px">
                <series>
                    <asp:Series ChartType="Line" Name="Series1">
                    </asp:Series>
                </series>
                <chartareas>
                    <asp:ChartArea Name="ChartArea1">
                    </asp:ChartArea>
                </chartareas>
            </asp:Chart>
    
    // and the codebehind to bind a simple tuple; Item1, Item2 ... ItemN is what you use to reference your tuple fields by name
      Random rnd = new Random();
      var records = new List<Tuple><DateTime , decimal>>();
      for (int i = 1; i <= 12; i++)
        records.Add(
          Tuple.Create(new DateTime(2010, i, 1), (decimal)rnd.Next(50, 500)));
      Chart1.Series["Series1"].XValueMember = "Item1"; // the field to provide the x coordinates for each plotted value
      Chart1.Series["Series1"].YValueMembers = "Item2"; // the field(s) to provide the y coordinates for each plotted value
      Chart1.DataSource = records;
      Chart1.DataBind();

There are quite a few things that I'm not mentioning as things that I personally care about but are, to be fair, things that you may find invaluable.  Here are a few:

  • While we'll inevitably have to use Entity Framework "4" (since we consult) we use NHibernate as our ORM whenever we have a choice.  Here are a couple of links on EF.  (The quotes around 4 are intentional; the current release is masquerading as 2 versions later in maturity!)
  • WCF, WPF and WF all have improvements to boast.  There's even a Microsoft REST offering coming along.  We use Mindtouch Dream, an open source alternative, instead for webservice communications and don't do a whole lot of fat client development anymore so these incremental improvements are not of immense interest to us.
  • Visual Studio.net 2010 debugging now supports multithreading.  (Pardon my ire on the tardiness of this offering as I could have used this in VS 6.0 12 years ago while fighting for hours with the Windows API during subclassing of the listview control?)

My only disappointment is in seeing Microsoft fall a bit behind in their cloud tool offerings.  They are talking the talk and Azure is well-conceived but the AppFabric won't be ready for another 3 months.  Until the tools are completely there and entrenched developers are not going to build in the cloud and business leaders will not join the party, at least not the party held by Redmond.  Jeff Bezos is still playing pied piper visionary very successfully.  Amazon continues to do nearly everything right and Rackspace's offerings are maturing very quickly.  As a developer who writes the majority of his code in a Microsoft language I'm hoping for more substance soon.

Tags:

Mar 28 2010

ASP.net MVC Internationalization (i18n/localization)

Category: ali @ 08:09

Yesterday I set out to add multi-language support to an ASP.net MVC application and had a bit more difficulty than I had anticipated.  The standard suggestions seemed to be "just do it like ASP.net webforms does it."  While having a literal point to a resource with a special tag DOES work in mvc (as displayed here for a resource named Title), why not take the opportunity to clean things up a bit and make them more flexible?

<asp:Literal ID="title" runat="server" Text="<%$ Resources:Title%>" />

First, some background.

There are two primary settings in .net relevant to localization: CurrentCulture and CurrentUICulture.  For an excellent explanation of what each does read this blog entry.  To summarize (and oversimplify), the CurrentCulture controls the formatted output of ToString() calls for dates and numbers while the CurrentUICulture is used to determine which alternative caption resource text to fetch at runtime.

There are 2 types of resources available to you with ASP.net, global and local.  Global resources are not tied to any user interface while local resources correspond to a UI element, most commonly an ASPX page.

K Scott Allen has a good post about ASP.net MVC localization here but the tidbits of knowledge he dropped didn't get me to a clean solution.  He does demonstrate that for simple projects the App_GlobalResources folder can be used and how to have the ASP.net runtime automatically associate CurrentUICulture

Lets meet the need for a global resource using a tip from Mr. Allen:

Add a new resource file to your project; I throw my global resources under Content but you can put it into any normal folder that you like. 

  • Add a resource string for testing purposes.  (The Name property is actually the key.) 
  • Now be sure to set the scope to be public in the dropdown provided at the top of the resource editor window. 
  • Go to the properties window settings for the file and set the custom tool namespace to be the same as your default namespace for your ASP.net mvc solution.

You can now reference your global resources from controllers or from your views like so.  (Here I'm referencing a resource by the key GlobalResourceTest located in a resource file named GlobalResources in the namespace MVCExperiment and putting the value into a ViewData field.)

	ViewData["Message"] = MVCExperiment.GlobalResources.GlobalResourceTest;  

localResourceExplorer

 

That takes care of global resources, but local resources are likely going to be a more common need.  To do those elegantly (and to avoid the Literal type syntax at the top) I gleaned a bit of knowledge and extension code from this blog entry by Matt Hawley.  Essentially you just need to add a special App_LocalResources folder in the appropriate location for your view to find its resources.  Go grab his resource extensions - you'll need them in a minute.

 

 

 

 

Once you've created resource files that the resource manager can find as depicted here you can now reference keys in an associated local resource file like so from within your views:

<%=Html.Resource("Title") %> 

In your web.config file add the following entry under configuration/system.web to have the asp.net runtime associate the visitor's preferred ui culture to your available ui culture:

<globalization uiCulture="auto" culture="auto"/> 

If you ever need to set the culture or ui culture explicitly you can do so as well with a line or two of code (say if you allow your user to see things in an alternative language explicitly by dropdown selection of language preference).

Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("es-MX");

Tags:

Feb 20 2010

LINQ to SQL - An Impressive, Lightweight ORM

Category: ali @ 01:08

A few months ago I finally trusted my first ORM with a production application.  <sarcasm>I'd been silly for far too long in turning down the prospect of giving up control over when and how my database calls were executed in order to save months of development time and to more fully realize the promise of object oriented development.</sarcasm>

When it comes down to it the most important thing that matters for an application is how well it is received by the user community.  One of the most endearing things a programmer can do for his/her users is to write blazingly fast code.  Unfortunately, the fastest code is often not the prettiest, nor is it usually the most elegant and maintainable.  Speed and control had prevented me from drinking the Kool-Aid, but they eventually got to me...

LINQ to SQL is a fantastic product in nearly eliminating the need to write code like this:

            using (SqlConnection cn = new SqlConnection(cnStr)) {
                SqlCommand cmd = new SqlCommand("spGetX", cn);
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(new SqlParameter("@param1", param1));
                List<customobject> results = new List<customobject>();
                using (SqlDataReader dr = cmd.ExecuteReader()) {
                    while (dr.Read()) {
                        results.Add(new CustomObject() {
                            Prop1 = db.Field1,
                            Prop2 = db.Field2
                        });
                    }
                }
                return results;
            }

Instead, you can say this with a LINQ to SQL data context around:

            return (from db in dataContext.spGetX(param1)
                        select new CustomObject() {
                            Prop1 = db.Field1,
                            Prop2 = db.Field2
                        }).ToList();

While the number of lines of code you see listed here don't look that different this is just about the simplest example, not to mention that the ADO.net code requires careful, manual editing of strings when database objects change.  The code at the bottom requires changes occasionally too but failure to execute them properly results in easy to find and correct compiler errors. 

The LINQ to SQL methodology is simple too - just drag and drop database objects from your Microsoft SQL Server (yes, SQL Server only unfortunately) to your .dbml file designer in Visual Studio.  Both your mappings and object definitions based on those mappings are completely generated for you when you click the Save button!  The simplicity is a triumph and, I have to admit, it must have saved several days of development time on that first LINQ to SQL production project .  It's just so much faster to deal with your data when your access to it isn't hindered by manual field definitions and related object definitions.

I've heard the speed of LINQ to SQL vs. direct stored procedure calls is around a 7% hit which I consider to be acceptable.  You can always drop back to using ADO.net directly and stored procedures in heavy traffic areas of your app, but neither you nor your users will likely ever notice a difference.  You and your users will enjoy the faster turnaround for database design changes though...

As with many good ideas from Microsoft, the future for LINQ to SQL has been discarded in favor of investment in their ambitious Entity Framework attempts.  Working with EF 1.0 was a real turnoff and I don't plan on revisiting that mess if I have a choice.  LINQ to SQL has a following so I don't imagine Microsoft will kill it or cut support for it in the coming 2 or 3 years but if you decide to use it on a project starting now you'll want to check on the official chatter before investing loads of time...

Tags:

Feb 20 2010

NHibernate Detached Criteria

Category: ali @ 00:25

I'm not going to discuss NHibernate, what it is or why you should consider it (over Entity Framework, for one) as an ORM.  I have nothing against the speed of stored procedures and ADO.net calls but the time it takes to write all of that code...  My snippet here is just to share a delight I had today in using NHibernate's DetachedCriteria in composing dyanamic SQL for one of the few methods that would ever require it.

This segment of code accepts a fluently composed instance of an app-specific criteria object and feeds it to an NHibernate session to retrieve data.

Having written this sort of code in several languages over the years I'm happy to see things getting more elegant over time : )

        
	public IList<app> Find(ApplicationQueryCriteria queryCriteria) {
            if (queryCriteria.Id > 0) { // a get against pk is always a preferable shortcut if we can do so
                List<app> result = new List<app>();
                result.Add(nHSession.Get<app>(queryCriteria.Id));
                return result;
            } else {
                DetachedCriteria criteria = DetachedCriteria.For<app>();
                if (queryCriteria.MaxResults > 0)
                    criteria = criteria.SetMaxResults(queryCriteria.MaxResults);
                if (queryCriteria.StartAtRow > 0)
                    criteria = criteria.SetFirstResult(queryCriteria.StartAtRow);
                if (queryCriteria.OwnerAccountID > 0)
                    criteria = criteria.Add<app>(a => a.OwnerAccount.Id == queryCriteria.OwnerAccountID);
                return criteria.GetExecutableCriteria(nHSession).List<app>();
            }
        }

A really polished solution to this situation would be handle the parsing of criteria objects internally to the criteria object itself and exposing the detached criteria instance (or something easily convertible to one).  However, that route would require defining a common interface among the criteria and the overhead of processing items into a collection only to be passed to another collection.  I'm skipping the added processing time and added coding time for now.

Tags:

Feb 16 2010

Migrator.NET

Category: ali @ 09:37

Source control is a great thing for a variety of reasons, among them the ability to work concurrently on a codebase without worry of overwriting each other's changes and the ability to go back to a codebase as it existed in a point in time.  Subversion, and more recently git, have this problem solved.  (Harper has recently been into git and has been impressed so far.)  What has traditionally been overlooked, however, is how to keep the state of your database in sync with your codebase.

It's not that developers don't see the need to keep their database changes in sync with their code.  (Stored procedures are nothing more than code stored on the database anyway!)  The problem has been how to accomplish the task.  Executing incremental DDL scripts to make every database change and saving those in a meticulous order is ornery in itself and it still doesn't give you the ability to undo one change easily...

Fortunately, several camps have started to address this issue.  The Ruby community brought the world migrations, which solves the problem through bringing database structure completely under the control of the source code using their ActiveRecord ORM.

As the saying goes, imitation is the highest form of flattery...

The Ruby on Rails methodology has been ported to .NET through an open source project (http://code.google.com/p/migratordotnet/).

We use this methodology to keep our database structure in sync with our codebase during development.  We've found it works well and is very little overhead to your development process.  An added benefit of this methodology is the ability to port the backend database for a given application to MySQL, SQL Server or other supported relational database in a matter of minutes.  (We don't like being tied to any one platform...)

For full details on how to get this setup refer to the author's instructions here (http://code.google.com/p/migratordotnet/wiki/GettingStarted).

Essentially you add a class library project to your solution and set a reference to the Migrator.Framework.dll.  Whenever a change is made to your database you create a new class in this migrations project.  Each of these classes only ever have 2 methods, an up and a down.  Up is a sequence of code run to execute the desired change and down is the logical reversal of those changes.  The Migrator.Framework assembly provides methods to translate your change intent to the database format you've selected.  Here's an example of a simple class:

    [Migration(20100121080900)]
    public class migration20100121080900_Add_SentAt_To_Invoices : Migration
    {
        public override void Up()
        {
            Database.AddColumn("Invoices",new Column("SentAt",DbType.DateTime,ColumnProperty.NotNull));
        }

        public override void Down()
        {
            Database.RemoveColumn("Invoices","SentAt");
        }
    }

In general we've found this means of tying database structure to code revisions to be very useful and helps us rest easy knowing that our database structure doesn't keep any "tribal knowledge" that exists outside of our source code revisions...

Tags:

Dec 15 2009

Cross-platform C# REST with MindTouch Dream

Category: ali @ 23:38

.NET asmx webservices were ok, then WCF came along and added a boatload of obscure configuration complexity with a few more features, but the future of webservice architecture seems to be REST (Representational State Transfer).  Amazon, Yahoo, Beanstalk and other public APIs commonly use REST and it is fast becoming the norm.  The only Microsoft-based C# framework that yet facilitates this means of service creation and consumption is based on WCF and is its infancy - see more details on that initiative here - the first beta bits just out a couple of months ago...  However, the developers over at MindTouch have thankfully created a REST service engine and client consumption framework that runs on mono.  Even better, they have exposed their framework, named Dream, as open source.  An overview of its capabilities, in the creator's own words, can be found here.

The first step in leveraging their considerable efforts in making REST easy from C# is getting your Dream server running to host your services.  That first step is the focus of this post.

As explained on the MindTouch Dream community page there are several possible configurations for a Dream server setup.  We are going to focus on IIS6 and IIS7 on Windows but there are options to run the Dream server from the command line, as a Windows service or on mono/Linux among others.

The following will take you through configuration of your Dream server, creation of your first service and verification that your service is working as expected.

  1. Create a new directory on your workstation that will host the Dream source code, right click and execute a subversion checkout (using tortoise svn) from the following location:
    https://svn.mindtouch.com/source/public/dream/
  2. Open <dreamSrcRoot>\trunk\src\MindTouchDream.sln using Visual Studio and build a release version of the code.
  3. Create a directory to be used as the IIS root for Dream services (c:\inetpub\wwwroot\dream if you have a default IIS installation and you use such paths)
  4. Create a directory structure under this newly established <IISDreamRoot> directory as depicted here dreamDirectories
  5. Define a new IIS website to serve port 8081.  This can be any available port but this is the Dream default.  Also, you can just as easily setup a virtual directory off port 80's defined website if you prefer.
    • Be sure to grant execute access to Scripts and Executables.
    • (REQUIRED FOR IIS6 ONLY) Create a wildcard script map by clicking the Configuration button on the Virtual Directory/Home Directory tab of the IIS properties dialog, clicking the Insert button and referencing C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll. As exhibited here, be sure to uncheck the "Verify that file exists" checkbox.
    • wildcardIIS6MapGrant Modify access to the data subdirectory and its children to IUSR_<machinename>, your Internet Guest Account (on IIS7) and NETWORK SERVICE (on IIS6)

  6. Copy and rename the IIS6.web.config file from <dreamSrcRoot>\trunk\src to <IISDreamRoot>\web.config
    *NOTE: For IIS7 (Windows 7/Windows Server 2008) copy and paste the IIS7.web.config file instead.  Also, on 7 place your dream.startup.xml file in your <IISDreamRoot> directory and change your web.config path appropriately.
  7. Create a new XML file using notepad or your XML editor of choice that contains the following.  This will be your Dream server startup script.  Save the file to <IISDreamRoot>\bin\dream.startup.xml 

    <script> 
    <!-- TODO: repeat the following line for each assembly that needs to be explicitly loaded --> 
    <action verb="POST" path="/host/load?name=DreamTestAssembly.EchoSvc" />  
    <!-- TODO: repeat for each service that needs to be started -->  
    <action verb="POST" path="/host/services">    
    <config>      
    <path>echo</path>      
    <sid>sid://sightsource.net/svc/echo</sid>
    <!-- TODO: add custom <config> elements -->
    </config>
    </action>
    </script>

  8. Open the web.config file in Visual Studio and edit the following entries to these values:
    • Set the Dream Server API key (think of this value as the password to your dream server installation)
      <add value="YourNewValueHere" key="apikey" />
    • Set the path to your Dream startup script (no bin subdirectory recommended for IIS7)
      <add key="script" value="bin\dream.startup.xml" />
    • Under the Log4Net settings section
      <file value="data\logs\dream.log" />
  9. Copy the contents of <dreamSrcRoot>\trunk\src\bin to <IISDreamRoot>\bin
  10. Create and publish your first Dream service
    • Open Visual Studio and create a new project of type Class Library, name it DreamTestAssembly
    • Set a reference to MindTouch Dream for your project by browsing to the <IISDreamRoot>\bin\mindtouch.dream.dll file
    • Change the name of the default class to be EchoSvc. Your code should look like the below. **Be sure that the sid value (sid://your/company/url/goes/here/svc/echo) matches EXACTLY to what you entered into the dream startup xml file above.
      using System;
      using MindTouch.Dream;
      using MindTouch.Tasking;
      
      namespace DreamTestAssembly {
          using Yield = System.Collections.Generic.IEnumerator<iyield>;
      
          [DreamService("Echo Service", "Copyright (c) 2010 Sightsource, LLC",
              Info = "http://sightsource.net/svc/catalog/test",
              SID = new string[] { "sid://sightsource.net/svc/echo" })]
          public class EchoSvc : DreamService {
      
              [DreamFeature("GET:{input}", "Simple response feedback test (GET ONLY) (testing installation success)")]
              public Yield Echo(DreamContext context, DreamMessage request, Result<dreammessage> response) {
                  string input = context.GetParam("input");
                  response.Return(DreamMessage.Ok(MimeType.TEXT,
                      String.Format("{0} - length of {1}", input, input.Length)));
                  yield break;
              }
      
              [DreamFeature("POST:{input}", "Simple response feedback test (POST ONLY) (testing installation success)")]
              public Yield TestPost(DreamContext context, DreamMessage request, Result<dreammessage> response) {
                  string input = context.GetParam("input");
                  response.Return(DreamMessage.Ok(MimeType.TEXT,
                      String.Format("POSTED DATA=[{0}] - length of {1}", input, input.Length)));
                  yield break;
              }
          }
      }
    • Copy your newly minted assembly dll from your Visual Studio /bin/release directory to <IISDreamRoot>\bin\services (it should be named DreamTestAssembly.dll)
  11. Open a browser and navigate to the following url, making use of your paste command.  You should receive an list of the known services (4 services should be running, the last being Echo).
    http://localhost:8081/host/services?apikey=YOURAPIKEYHERE
    *NOTE: If you setup a virtual directory rather than a website service listening on port 8081 your url should look more like the following:
    http://localhost/dream/host/services?apikey=YOURAPIKEYHERE
  12. Test your service. It will be accessible through the following URL for a GET (if you have configured a website on port 8081), followed by any parameter patterns you choose.
    http://localhost:8081/echo/test
    You should receive test - length of 4 as your successful response.

The good news is that all that must be done to add to your service repertoire from now on is a simple add to the configuration entries in the dream.startup.xml file appropriate to your additional service sid and to copy the relevant assemblies into the services subdirectory.

Get additional details regarding alternative setups directly from the official MindTouch dream page.  It also offers a couple of additional tutorials to try out on your new installation.

Since Microsoft does have REST support on the way you may be conflicted.  Should you go Dream or WCF REST?

Two reasons have led us to go with Dream.  It runs on Mono so isn't tied to Windows and it's been around for a couple of years, not a couple of months so it should be more mature, at this point at least, than the new shim on top of WCF.

Happy Coding!

Tags:

Dec 15 2009

Cloud Computing - One Interpretation

Category: ali @ 10:33

There is a lot of hype over what is sometimes correctly, sometimes inaccurately, being called Cloud Computing.  It is worth the time to cut through the marketing propaganda and to understand the opportunities this holds; some will evaporate as this method becomes status quo. When you understand the value proposition you'll see if and how the features of this new landscape may or may not pique your interest.

In a nutshell cloud computing is cost-effective, Internet scale computing available on demand.  For many people who have no need for near 100% uptime or massive scalability all of the hype is just that, noise.  However, for some of us out there who are familiar with the high prices and sometimes unreliable nature of homegrown or regional DataCentres this turn of events has been high on the wish list for a long time.

Consider the average corporate DataCentre of today.  It probably employs 10+ people, consists of > $1M USD in hardware, software and other accessory licensing and local contingency assets and has a high monthly expense burn rate.  Now, add the cost of off-site redundancy through a 3rd party company like Sungard and you probably increase the annual cost by at least a couple hundred thousand.  If you aren't familiar with the costs associated with these services you may already have your head spinning, but the sad truth of the matter is that no matter how hard the people in this configuration work nor how well the individual components are configured and maintained they will very likely fail to be as reliable and as available as a best-in-class business that focuses on nothing but this service.  (Examples include EngineYard, Rackspace or one of the many others.) It's a simple matter of focus and investment, not really one of capability.

Is there a better way?  Sure.  Let the specialist companies reap their economies of scale and prosper as a result of their focus by hiring them to solve your hosting needs also.  This has traditionally not worked well, and won't for a while yet, for two reasons.  The first is cost and the second is feasibility.

  1. Cost: These hosting companies like to market themselves as partners in meeting your needs.  In reality they are not setup to change their processes or bend over backwards to meet your specific company's configuration.  They would lose their economies of scale through customization if they chose that path and they are too smart to go down that road.
  2. Feasibility: No matter how great a hosting company is at hosting, they are great at hosting things in THEIR DataCentre where THEY have complete control over every facet of the environment.  When a mature enterprise approaches such a host the prospect of moving interconnected applications piecemeal to another network at another physical location is in the worst case just not possible and in the best case fraught with support, trust, management and middleware issues.

The cloud is eliminating the cost problem (it costs $0.12 per hour to run a Microsoft Windows Server 2008 instance on the Amazon EC2 cloud right now and less for Linux). 

The feasibility problem is not so easy to mitigate but the cloud is helping in the same way that Capitalism is conducive to invention.  By making servers, configurations, redundant disk and other traditionally high priced DataCenter resources accessible to the masses (it currently costs $0.15/GB/month to store information in the Amazon S3 cloud) those with creative ideas, hunger for innovation and a desire to change things now can experiment.  It's as if the scientists of the world have each been given their own labs to work in whereas before only 1% of them could afford to practice their hypotheses.  Will an increased rate of innovation result?  You tell me.

The only thing standing in the way of corporate migrations to the cloud are concerns about security and remaining friction in the feasibility arena.  With Amazon leading the way with ideas such as CloudFront, Virtual Private Cloud (VPC) and AWS Import/Export, with Microsoft?s focus on .net Services or Windows Azure or SQL Data Services or whatever they're calling it this week, with Rackspace trying to get into the game and big players like Google, VMWare and IBM announcing their strategic initiatives focusing on offering cloud resources I?m not the only one to see where this is going.  It has turned into a race to this new platform.  By 2015 hosting your own DataCenter will be like writing a new Windows fat client application - an obsolete, bad idea that should be avoided if at all possible!

Sightsource are focusing our efforts on making application migration/rewrite into the cloud-based architecture easier.  We're also building our SaaS apps to run natively on geographically diverse, non-relational databases and scalable cloud computing instances from the start.  Call us optimists, but we like the idea of essentially infinite scalability and redundancy out of the box without any additional cost.  We don't care who wins the cloud wars.  We're cloud enablers that are focusing our efforts on Amazon and Microsoft for now and others as their offerings in this space mature.

Tags:

Dec 13 2009

ASP.net mono on Amazon EC2 (Ubuntu Karmic) - Quickstart

Category: ali @ 09:22

By now you've heard about cloud computing and maybe you want to see what it's all about.  If you've done any sort of investigation into the Internet hosting offerings available, either cloud-based or not, you already know that the cost for a Windows instance runs about 25-30% more expensive on average.  The cloud is no exception.  (If you're not familiar with Amazon's very impressive platform leading computing into the future check out what they're up to at the AWS (Amazon Web Services) website.)

If you are a .NET developer, specifically ASP.net as most of us are, you have also probably heard about mono - the fantastic open-source initiative to port the .NET runtime to Linux.  What was just a dream a few years ago is now a production-ready, solid platform with features matching the .NET runtime through version 3.0 (as of the time of this posting).

Combine mono runtime + a current Linux OS (Ubuntu Karmic in our example today) and you can free yourself from the chains of Windows and the associated comfort tax.  (Don't get me wrong, Windows Server 2008 is a great OS but I've never been one to pay for things I don't have to.) 

The site you're viewing right now has been served to you by an Apache 2 server running on Linux.  That alone would not make this extraordinary in the least, but the runtime is pure C#, ASP.net.  Mono is the technology making this possible.

As an added bonus you may also find that your code runs faster on Apache vs. IIS.  Enough of whetting your appetite, lets see it work!

The below assumes that you are using Windows on your client/admin computer; the client/admin computer setup will be somewhat different if you are on a Mac or Linux.

  1. Create an Amazon EC2 account
    • Go to http://aws.amazon.com and click on the Sign Up Now button at the top, right.
    • Go to http://aws.amazon.com/ec2/ and ensure that you have enabled your AWS account to use the EC2 (Elastic Compute Cloud).  For some reason, you need to enable your account to use each subset of Amazon services, such as S3 (Simple Storage Service), SimpleDB (a geographically redundant, non-relational database service),  SQS (Simple Queue Service) or others.
    • Take note of both your AWS Access Key and your AWS Secret Access Key as they will be needed momentarily.  If you don't see them you will be able to find them by navigating to the Security Credentials menu under the Your Account portion of the AWS administration website.  They will either be sitting there waiting for you on the Access Keys tab or you can choose to create a new pair.
  2. Download and install the necessary, local utilities
    • Putty, PuttyGen, Pageant and Plink - Download and install all 4 of these from the putty download page.  These will be necessary to easily communicate with Linux from Windows.
    • WinSCP - Download this from here and install it.  It is used to transfer files between your computer and your cloud instance(s).  (If you're familiar with FTP and FTP clients like WS_FTP this is the secure equivalent.)
    • Firefox - The Mozilla Firefox browser can be downloaded from the firefox download page.  If you've never heard of it - it is a leading-edge browser on par with Internet Explorer and almost as fast and as stable as Google Chrome ; )  In this case Firefox is necessary solely to use the very useful Elasticfox browser plug-in.
    • ElasticFox - Download this utility from this AWS page. It is a plug-in for the Mozilla Firefox browser and is one of the more polished ways of interacting with your EC2-related assets from a web-enabled workstation.
  3. Create a new EC2 KeyPair
    A keypair can be thought of as a secure logon credential with both the username and password generated for you. You will need at least one to be able to access your instance after you create it so you need to create at least one for your account. (Amazon explains the full details here.) PuttyGenSuccess
    • Open the Firefox browser
    • Select Tools/Elasticfox to launch the elasticfox control panel
    • The first time you open elasticfox the utility will ask you for your account credentials.  This is the AWS Access Key and AWS Secret Access Key you received when signing up for an AWS account, above. 
    • Go to the KeyPairs tab and click the new keypair button, provide a name for your keypair and save. **BE SURE TO SAVE THIS .PEM FILE TO A KNOWN, SECURE LOCATION**  It will be difficult if not impossible to find this private key to the new keypair if you lose this file.  (It's actually not that big a deal / you just create another one but why waste the time?)
  4. Convert your KeyPair to be usable
    • Open PuttyGen (it will be at C:\Program Files\Putty\PuttyGen.exe if you accepted the defaults during the installation)
    • Click the Load button at the bottom, right and select the .PEM file containing the private key for your keypair generated above.  (You will need to change the filter to see 'All Files' to be able to see the .PEM files.)
    • You will be presented with a success message like the one displayed here. 
    • Click the Save Private Key button at the bottom, right and choose to save the .PPK file "without securing it" and close PuttyGen 
  5. Use Elasticfox to launch an instance
    • By default AWS EC2 instances are strictly limited in who can connect to them by ip address and port.  (This is a feature and should help you sleep better at night once you have assets on the cloud.)  However, you must grant yourself access to administer your own instances by ip address and port.  Fortunately this is not difficult.  AWSSecurityGroupPermissionClick the Security Groups tab in elasticfox.  Select (or create a new and then select) a security group on the left.  Click the Grant Permission checkbox icon in the right panel to display the below dialog.  To enable your own, current IP address to connect by remote command line (SSH) you can select SSH as protocol details, click the Get My Host Address button at the bottom, right and click the Add button. AWSLaunchInstance
    • Click the Images tab to be shown a list of available Amazon Machine Images (AMIs).  Each of these are pre-configured images available for you to launch and begin playing with immediately.
    • Filter for the AMI named ami-1515f67c by typing its key into the textbox and pressing enter.  (It is a Ubuntu Karmic image well suited for mono and apache installation.)
    • Right click on the AMI record displayed and select Launch new instance(s) of this AMI from the context menu.  Provide an instance tag, your desired keypair name and your desired availability zone and then click the launch button.
       *NOTE* Security groups cannot be removed after launch, only altered; create necessary security group as required.
      Also, if on a Mac or Linux you can right click on the new instance and choose "Connect To Instance" and it will actually work by successfully launching Putty and logging you in.
    • Elasticfox will take you to the instances tab to show you that there is a new instance in a PENDING status. Within a minute or so the status should go to RUNNING.
  6. Connect to the command line of your new server instance using Putty
    • Right click on the running instance you've just launch in Elasticfox and select the 'Copy Public DNS name to clipboard' from the context menu
    • Open Putty (it will be at C:\Program Files\Putty\Putty.exe if you accepted the defaults during the installation)
    • Paste the contents of your clipboard into Host Name (or IP Address) box near the top of primary Putty window.
    • In the hierarchical navigation on the left click the Connection/Data node
    • Type ubuntu as the Auto-login username at the top (this is necessary for the Karmic version of Ubuntu and is different for other flavors/versions of Linux)
    • In the hierarchical navigation on the left click the Connection/SSH/Auth node
    • Set the Private key file for authentication field by browsing/selecting the .PPK file you saved for the associated keypair above
    • Click back on the Session node at the top, left
    • Type a name for this instance setting into the Saved Sessions box and click the Save button.  (On future visits to Putty simply select the setting name and click the Load button to use this profile.)
    • Click the Open button at the bottom to open a remote command line interface to your server
    • If you get a blank console window with no response your current IP address is very likely not allowed to connect to your instance.  The fix is to add your current IP address to one of the security groups associated with this instance.  (This process is outlined above.)
  7. Install the necessary utilities on your server

    The following is all you need to download and install OS updates, apache, mono and configure for hosting your site. (Makes you wonder why the equivalent would take such a long time in Windows, doesn't it?)

    • Set the remainder of your session to run with elevated user rights
      sudo -s
    • Update the system with the latest patches
      apt-get update
    • Install Apache 2 (type y when prompted)
      apt-get install apache2
    • Install the latest Mono runtime (type y when prompted)
      apt-get install mono-runtime
    • Install mod_mono - the Apache plug-in for ASPX processing (type y when prompted). This will hang while restarting Apache / don't panic, just press CTRL+C to get back to the command line.  Run the same command a second time and this time it should succeed.
      apt-get install libapache2-mod-mono
    • To verify type the following command in an attempt to enable mod_mono explicitly and you should receive a 'Module mod_mono already enabled!' message
      a2enmod mod-mono
    • At this point you will be able to see your server serving pages on the Internet (if you've allowed TCP/IP port 80 access in an associated security group for your instance, above).  Simply open your favorite browser, paste the public DNS name of your instance into the browser's address bar and press enter.  You should have a default page come back with an 'It Works!' message.
    • Leave this SSH session open - you'll need it in a minute to create/alter files during the site migration process
  8. Upload your aspx site to your new instance
    • Open WinSCP (it will be at C:\Program Files\WinSCP\WinSCP.exe if you accepted the defaults during the installation)
    • Click the New button at the top, right
    • Paste your public DNS name for your instance into the Host Name box
    • Type ubuntu into the Username box
    • Browse/select your .PPK file correspondent to your keypair for the Private key file box
    • Select SCP from the File Protocol dropdown list
    • Select the Environment/[SCP/Shell] node in the hierarchical list on the left
    • Select sudo su - from the Shell dropdown list at the top
    • Click the Save button and paste your public DNS name to save this profile for later use in WinSCP
    • Click the Login button (click OK to the verification box) and you will be presented with a view of your local file system on the left and your server's file system on the right.
    • Switch back over to your SSH session, navigate to the Linux equivalent of C:\inetpub\wwwroot (/var/www on Ubuntu Karmic) and create a root application directory for yourself using the following commands
      cd /var/www
      *NOTE: ls is the equivalent of the dir command on Windows
      mkdir YOURSITENAMEHERE
    • Switch over to your WinSCP session, ensure your right panel is sitting in your /var/www/YOURSITENAMEHERE directory and copy over your application files from your local computer (selecting files on the left and pressing F5 is a shortcut to do so)
    • Open your favorite browser window and navigate to this very helpful mono/Apache utility. Use it to generate an Apache configuration file to define your new site.  Save the generated file to your local file system named YOURSITENAME with no extension.
    • Use WinSCP to migrate this newly-generated file to the following remote directory
      /etc/apache2/sites-available
    • Enable Apache to serve the new site using the following command
      a2ensite YOURSITENAME
      *NOTE: Use a2dissite YOURSITENAME and then reload your config to disable your site
    • Tell Apache to reload its configuration and restart so it will begin serving your newly configured site
      /etc/init.d/apache2 reload
      /etc/init.d/apache2 restart
      *NOTE: Other very useful Apache commands include reload, restart, start and stop
  9. Deactivate your instance when done 
    It is important to stop any running instances you don?t need because you will be charged for every hour it is running.  The straightforward moral of the story is to turn the lights off when you leave the room!  There are a couple of ways to deactivate a running instance.
    • You can find a list of all of your running instances on the Instances tab of your Elasticfox interface. Simply right click on a running instance and choose "Terminate" to send a shutdown request.
    • Alternatively, you can SSH into your running instance and simply type halt at the command line. That will cause Linux to shutdown immediately and stop any charges from accruing related to that instance.
    However you choose to shutdown your instance do not be alarmed that the instance will likely hang around on the instances list of your elasticfox interface for a while as a "TERMINATED" status. This will eventually disappear in half and hour to an hour.

The current AWS pricing table shows the small cost associated with this power.  At currently $0.12 per hour for Windows (small) instances, $0.085 per hour for Linux (small) instances and reductions below that for reserved instances what's stopping you from spinning up your own server(s), playing to your heart's content and then deactivating them when you're done?!  (Instance type definitions of small, large, etc. are available but you'll be pleasantly surprised that 'small' = 1.7GB of RAM, 160GB of disk and 1.0-1.2GHz Opteron or Xeon processor.)

It will very likely cost you less than the cost of one day's lunch to play with cloud server(s) for an entire month.  (Just remember to shutdown your instances when you logoff!)

As of the time of this writing Amazon has just released the Amazon Management Console (https://console.aws.amazon.com/ec2/home).  It is a completely web-based administrative console and it may make some of these operations even easier, but for now it seems to just mimic the features you already have through Elasticfox.

If instead of the above setup of Apache to serve asp.net from the EC2 cloud there is, of course, the simpler path of hosting your application on Windows.  Amazon provides a walk-through of that process here.  Regardless - make the most of the new power at your fingertips!

Tags:

Nov 15 2009

jquery Ajax

Category: ali @ 23:32

The elegance of jquery continues to impress me.  Writing very powerful code at a high level against CSS identifiers cleans up the old XMLHttpRequest stuff we had to do not so long ago.  Creating impressive, integrated sites that don't flicker or noticeably postback will soon become a matter of course (just like use of CSS to style pages over html attributes did a few years ago).  The emergence of a dominant javascript library (jquery) will hasten this positive development for the user experience.  (Microsoft deciding to integrate it as part of its development foundation will only strengthen this position.)

Rather than ramble on about jquery I wanted to show 1 specific use that meets a common, current need in development of the user interface of a modern web application.  That is the rewriting of pages dynamically (no postback) based on user interaction with a page or based on a specified refresh time using javascript's setTimeout().  With the very

$(document).ready(function() { 
  $.ajaxSetup({ // done for convenience - all this does is setup defaults for later ajax calls so these settings need not be repeated on each call
	dataType: "json", 
	contentType: "application/json; charset=utf-8", 
	type: "POST", 
	cache: false 
  }); 
  reload(); // of course, this can be set to refresh with a specified frequency using setTimeout or directly via page events rather than just once on load 
}); 

function reload() {
  $.ajax({ 
	data: "{'p1':'someParamValue'}", // <- (optionally) sending a JSON parameter 
	url: "https://Url/Of/Your/Webservice/Goes/Here", 
	success: function(rawMsg) { 
		var msg = eval('(' + rawMsg.d + ')'); // <- casting back to a list of objects to be consumed, this response from an asmx c#.net service, 3.5 SP1
	// this is where app-specific processing of the message occurs using standard js 
      		$('table#tbl tbody').html(rows); // 1-line page rewrite of the rows associated with a table on this page 
	} 
  }); 
}
<table id="tbl" cellspacing="0" cellpadding="0">
<thead>
<tr>
  <th style="width: 50px"></th>
  <th style="width: 80px">Status</th>
</tr>
</thead>
<tbody></tbody>
</table>

The tbody tags will be filled by the ajax call to a webservice providing data of interest to your application.  The thead section is hardcoded HTML to provide some initial structure to the table, including column widths.

Tags:

Nov 15 2009

CSS Center In Page

Category: ali @ 23:08

I know, it's a common trick of the trade, but I've put it here for just one more reference.

When positioning a site's content div in the center of the viewable screen it is common to create a div that will be used as the container for content of all pages.  That div is most often centered and set to the least common denominator screen resolution for all client computers that will consume the site (or the lowest screen resolution considered to be reasonable by the development team : ).  Setting a couple of CSS properties, like so, does the trick.

body { 
  text-align:center; 
} 
#content {
  width:760px; 
  margin:0px auto; 
} 

<div id='content'>All of your interesting functionality goes here</div>

To get your div centered in older IE browsers also you must take advantage of an improper treatment of the text-align property in those browsers.

Tags: