Pages

Tuesday, May 31, 2011

Quick Windsor Example

Castle.Windsor, an IoC container, can be implemented in multiple ways. Here is one of them. I find it rather simple and flexible. Here is a quick example on how to get it up and running in a project.

The code is only a few lines:

        private void RegisterIoC()
        {
            var container = new WindsorContainer(
                new XmlInterpreter(new FileResource("castle.config")));

            var outboundMessageHandlerStrategy = container.Resolve<IOutboundMessageHandlerStrategy>();
        }

The configuration is read from castle.config file, where the components are configured. This allows for flexibility and making the module replacement a configuration change instead of code change.

The castle.config looks like:

<?xml version="1.0"?>
<configuration>
  <components>
    <component id="taxcalc.service" 
               type="IoC.Tutorials.Part1.TaxCalculator, IoC.Tutorials.Part1" />
  </components>
</configuration>

The type name and namespace do not match the code above, btw, but the principle is there.

Another other option would be to use fluent interface to configure the container, as below.

            container.Register(Component.For<IOutboundMessageHandlerStrategy>()
                .ImplementedBy<WCFOutboundMessageHandlerStrategy>().Named("blah"));

At the moment, this is the work in progress. I'll get to finalize this example when I'm back to the task that involves Windsor.

 

Saturday, May 28, 2011

MP3 AudioBooks in iTunes

I just found a piece of advice that seems quite useful for MP3 versions of audiobooks:

There is no need to download or convert to bookmarkable (remember your place in the book where you were there last) mp4 (.4mb) format for i-Pods or i-Phones. 

If you don't want to download or convert to 4mb here is what to do if you want your mp3 Audiobook files to be "Bookmarkable". (Look Like Audiobooks)

Open iTunes, click on "File" tab and select "Add Folder to library". Click the mp3 file or files in i-Tunes, choose get info, go to the options tab, tick "Audiobook in Media kind ", and then tick "Remember position" & Skip When Shuffling".

Job done.

Friday, May 27, 2011

Code-First, EF 4.1, SQL Compact

Entity Framework 4.1 now fully supports SQL Server Compact for Code-First Development with ASP.NET MVC 3. There are a few gotchas still, especially considering that CTP versions of libraries had workarounds and are therefore incompatible with the RTM. But since they are still available as NuGet packages, this might be confusing for the beginners. It certainly was for me.

So, here are the steps:

  1. Create an MVC 3 application.
  2. Create Model classes.
  3. Scaffold the controllers and views.
  4. Add the connection string to Web.Config
  5. Adjust Global.asax Application Start 

Connection String

 

    <add
    name="WithCompactContext"
    connectionString="DataSource=|DataDirectory|MyDb.sdf"
    providerName="System.Data.SqlServerCe.4.0"/>

 

Global.asax::Application_Start

            System.Data.Entity.Database.SetInitializer(
                new System.Data.Entity.DropCreateDatabaseIfModelChanges<WithCompact.Models.WithCompactContext>());

This option tells the EF to recreate the database if model changes. Tip: make sure you don't already have the database file created when working with SQL Server Compact, otherwise the following errors pops up

Model compatibility cannot be checked because the database does not contain model metadata. Ensure that IncludeMetadataConvention has been added to the DbModelBuilder conventions.

 

MIX 2011 Videos

Presentations from MIX 2011 are available at Channel 9:

http://channel9.msdn.com/Events/MIX/MIX11

Wednesday, May 25, 2011

Coexisting WebForms and MVC

In addition to my previous post on the topic, here are the steps to take if MVC is to be added to an existing WebForms project:

  • Add references to
    • System.Web.Routing
    • System.Web.Abstractions
    • System.Web.Mvc
    • System.Web.Helpers
  • Add directories to the existing site root
    • Controllers
    • Views
    • Content (optional) for images and CSS
    • Scripts (optional) for JavaScript
  • Update web.config to load the above assemblies at runtime and register the UrlRoutingModule
  • Set route(s)

If you decide to keep the default route then either copy (from a blank Mvc project) or create a new HomeController and the view(s) for the actions. The best way is to do the above tasks manually and then copy the content, like controllers, views, and scripts, from a starter Mvc site.

Web.config

These are the settings to add to web.config:

    <compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>
</compilation>

and also

  <system.web>
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages"/>
</namespaces>
</pages>
</system.web>

 

Code-First Development with Entity Framework 4.1

Entity Framework 4.1 is delivered with MVC 3 (Tools Update). It allows for easier Code-First Development, which means creating custom busines objects/entities and repositories (data context), and then mapping them to the database. Rather than the other way around, which is usually the case (unless you use NHibernate and have known about this for years :).

One issue that I ran into when using Code First Development was that I tried to add my own objects to the project that already had an .edmx model generated from the database. For some reason EF goes nuts and things just don't work.

The solution to that is to remove .edmx in some way. Either rewrite the objects to use Code First or separate them into separate assemblies.

For more info, see

http://social.msdn.microsoft.com/Forums/en/adonetefx/thread/4d9846a0-f890-41df-9444-cf2b4d2bd710

All the code that needs to be written is the Model. I use the following classes as a start:

 

public class WorkItem
    {
        public int Id { getset; }
        [MaxLength(100)]
        public string ItemName { getset; }
        public int WorkOrderId { getset; }

        public virtual WorkOrder Order { getset; }
    }
    public class WorkOrder
    {
        public int Id { getset; }
        public string Title { getset; }
        public DateTime? OrderDate { getset; }

        public virtual ICollection<WorkItem> Items { getset; }
    }

 

SQLite AutoIncrement columns

SQLite

I'm using SQLite for data storage in the quick proof-of-concept sites. One thing that is convenient to have is autoincrement Id field so one does not have to write own code to maintain the uniqueness, having more time to focus on actual work that the application is supposed to do.

While I've been trying different keywords, from different suggestions over the web, it turns out the AutoIncrement functionality is already built in SQLite and kicks off automatically when the Id field is of type Integer. Also, bear in mind that Integer here is int64 so there's plenty of values for most of the common scenarios.

Short answer: A column declared INTEGER PRIMARY KEY will autoincrement.

See http://www.sqlite.org/faq.html#q1

Entity Framework

Since I am using Entity Framewok to work with the data in SQLite database (MVC Scaffolding makes it so easy to utilize this), I ran into an issue where inserting the first row works but any subsequent row will get rejected by the SQLite. The reason for this is that EF sends 0 (zero) in the Id field while SQLite expects NULL. See below link for more details.

http://stackoverflow.com/questions/936804/sqlite-with-entity-framework

The solution for this is to explicitely mark the Id field with AUTOINCREMENT. To do this, I use SQLite Manager, Mozilla Firefox plugin, which allows me to get the SQL DDL for the table, manually add the 'autoincrement', drop and recreate table by issuing SQL commands.

Also, in the EF model, I set the Id columns StoreGeneratedPattern value to 'Identity', while some even suggest to use 'Computed'. 

Tuesday, May 24, 2011

Passing quick data to Views with ViewBag

The new ViewBag is a dynamic wrapper around ViewData that allows passing the data from controller to the view. One of the issues at the moment is that ViewBag contents can't be passed to HTML Helpers as parameters directly.

The workaround for this is to explicitely cast the ViewBag property to the expected type.

So, instead of

@Html.TextArea("customXml", ViewBag.CustomMessage, new { @style = "width: 100%; height: 400px; " });

you'd have to write

@Html.TextArea("customXml", (string) ViewBag.CustomMessage, new { @style = "width: 100%; height: 400px; " });

Passing data with RedirectToAction

This might be a result from the WebForms-centric way of thinking and a dirty habit, but I need to have the following flow on the web site:

  1. User clicks a button (or submits some data in another way)
  2. This posts the form to the Home controller.
  3. Home controller transfers the data to another controller's action

I tried using the default route's 'id' parameter but this puts a long XML into the address field in the browser and, besides, just doesn't work.

The right option for this scenario is using TempData. This translates to simply using 

            TempData.Add("customMessage", xmlContent);
            return RedirectToAction("Index""CustomMessage");

in the Home controller, and 

            var xmlContent = (string) TempData["customMessage"];

in the receiving controller. (Passing the same data to the view is another matter. Using ViewBag is the 'quick & dirty' way. See related post.)

"The TempData property value is stored in session state. Any action method that is called after the TempDataDictionary value is set can get values from the object and then process or display them. The value of TempData persists until it is read or until the session times out."  

Source:

http://stackoverflow.com/questions/5753720/passing-info-to-another-action-using-redirecttoaction-mvc

dotPeek - .Net Decompiler from JetBrains

dotPeek is a free .Net decompiler being developed by JetBrains. 

http://confluence.jetbrains.net/display/NETPEEK/dotPeek+Early+Access+Program

Monday, May 23, 2011

KnockoutJS

Knockout is the Model-View-View Model pattern for JavaScript UI. It encapsulates data and behavior into a view model, which provides a foundation for data-binding of DOM elements and frees the developer from manually wiring the data to the UI elements.

http://knockoutjs.com/

Sunday, May 22, 2011

MVC Visual Studio Helpers

If you mix Web Forms and MVC in the same project, Visual Studio helpers for MVC come in really handy when adding Controllers, Views, and so on. It is as easy as right-clicking the Controllers directory and the Add menu will display "Controller" at the top of the list. This is really convenient. Depending on the context, the destination of the right-click, different options will be displayed in the Add menu.

However, if you are modifying an existing Web Forms project to work with MVC, these options will not be available by default. The fix is simple.

In your existing Web Forms project's .csproj file, locate line

    <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

and add one more guid at the front, so that it looks like this:

    <ProjectTypeGuids>{E53F8FEA-EAE0-44A6-8774-FFD645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

Now all the options available at the MVC project will be available in the (previously) Web Forms Application project.

 

Mixing ASP.NET WebForms and MVC

MVC is a wonderful framework to work with. Unfortunately, there is lots of existing material and sites that are written using WebForms and these require maintenance. Going by the maxim "never leave the code untouched", I reckon that these sites and code shoud be refactored bit by bit and transitioned towards using MVC.

It is, of course, not practical nor beneficial to rewrite whole applications but adding new functionality and refactoring the old should also encompass replacing bits and pieces with MVC framework. So, in that regard, here are some pointers as to how to mix multiple existing technologies, all hosted on IIS:

  • Plug-In Hybrids: ASP.NET WebForms and ASP.MVC and ASP.NET Dynamic Data Side By Side, Hanselman (link)
  • Mixing ASP.NET Webforms and ASP.NET MVC, PacktPub (link)
  • asp.net-mvc and webforms co-existing, Stack Overflow (link)

Saturday, May 21, 2011

Synergy - Share your mouse and keyboard

As my PC was unreliable just when I needed it the most, I got a laptop to do software development. Now it looks quite cumbersome to switch keyboards to work on the two machines so I was looking for a solution that would enable me to use my keyboard and mouse on both computers. And, here, the solution is Synergy.

Synergy is Free and Open Source Software that lets you easily share your mouse and keyboard between multiple computers, where each computer has it's own display. No special hardware is required, all you need is a local area network. Synergy is supported on Windows, Mac OS X and Linux.

The first thing I liked about their site is that they are using Redmine! :)

http://synergy-foss.org/

Wow! Now that I've installed it, I can't believe it is this simple and easy! Screens are configured graphically, as per their physical location in relation to one another. Then, simply move the cursor over the edge of the screen and you're on another computer! Mouse and keyboard work on the selected workstation. Of course, only the Server's response to keyboard and mouse events is perfect, while the rest travels over the network but, for all sakes and purposes, it is decent enough for standard use. I can hardly notice that these are not the two computers anymore. The feeling is as this really *is* a single platform.

Awesome work, guys!

One problem I've noticed is if you open Resource Monitor on Windows 7, that somehow kills Synergy on that screen/computer (I only have one screen per workstation so can't tell for sure). If you had Resource Monitor (RM) open before starting Synergy, then both will work fine, except that you won't be able to operate or close RM window. :) 
This happens if you run Synergy as as ordinary user and then open an application that requires elevated privileges to run. So, in order to not experience these issues simply run Synergy "As Administrator". 

Another beautiful thing that feels natural when you work in this fashion is that Copy/Paste works across the workstations. This works for text (and maybe some other clipboard content) but not files. File transfer is quite cool with Dropbox LAN sync or just sharing folders through Windows.

Monday, May 16, 2011

ReSharper 6.0 Nightly Builds

ReSharper 6.0 nightly builds are available from the link below. These are used as an evaluation. The JetBrains instructions state:

Evaluation license
If your evaluation has expired, please install the lates build and choose 'Free evaluation' option on the License Information dialog
You can also use the following evaluation license:
User Name: ReSharper EAP User
License Key: 0-i5LycolHMT9ahzFH4R2Bt8gGiS40VYmU
Valid until: 05/30/2011

link

Sunday, May 15, 2011

MvcScaffolding: One-to-Many Relationships

Recently I've looked again at the most rapid way to implement basic CRUD for a relational data, using web application in .Net. From experience I knew that Web Forms had ways of getting this sort of thing done in a quick (and dirty) way. That was made even easier with recent version of WebForms. Now, looking at what MVC can do, I was quite pleasantly surprised.

A couple of weeks ago I looked at Scott Hanselman's presentation where he demonstrates some MVC Scaffolding templates. This was the missing bit but the things are falling into place. T4, NuGet, and now scaffolding. There are templates for a few things already and there will obviously be more in the not-so-distant future.

Here is an article in an excellent series about MVC Scaffolding. Steve Sanderson explains how to do one-to-many relationship and CRUD through a scaffolding template. He is using Entity Framework Code First approach to generating the data model. The templates do the rest in generating controllers and views, as well as the model.

Refresher

A range of interviews I've had in the past several wees prompted me to create a reference list of books and material every developer/architect should know. The list of material is available here.

A few books that I was really delighted with are Robert C. Martin's series - Clean Code: A Handbook of Agile Software Craftsmanship, and Agile Principles, Patterns, and Practices in C#.

All the material at the Books page is excellent and contains the core of what one needs to know in their everyday work. It is also a good refresher for people who have been focused on a small set of solutions and technologies at any given time. Happy reading.

Monday, May 09, 2011

NBuilder

A cool tool for generating test data. From the project description:

Through a fluent, extensible interface, NBuilder allows you to rapidly create test data, automatically assigning values to properties and public fields that are of type of the built in .NET data types (e.g. ints and strings). NBuilder allows you to override for properties you are interested in using lambda expressions.

NBuilder is an open source project, hosted on google code

As stated above, this software generates data that can be used for testing when you need lists of random data.

Tuesday, May 03, 2011

Galcon Fusion

I've just been introduced to this cool game. It is a great thing to play on iPad either in a duel or collaboratively. 

There is also an online version available and it includes multiplayer! Check out:

http://www.galcon.com/flash/play.php