All posts by Rikard Ottosson

About Rikard Ottosson

.NET developer. Father. Couch potato. Old, cynical, willing to learn, but quick to judge. Likes old hard rock. Hope to buy more guitars.

More Castle Windsor

In an unexpected move, I decided to go back and demonstrate the automatic injection of dependencies in the old Castle sample app from before. I did so because, well, not doing so I felt kind of missed the entire point of dependency injection.

Code Changes

There are a few initial changes to the source worth mentioning: I renamed the DataSourceFacility assembly to simply DataSource as I wished to avoid the ‘Facility’ word which has a different meaning altogether in the context of Castle Windsor.

As I hinted in the previous blog post I lifted the data access method  from the HomeController class to a dedicated data factory consumer class (cunningly name FactoryConsumer) in the DataSource assembly. To maintain an air of civility I also defined a new interface IFactoryConsumer which the FactoryConsumer class would then implement.

 

using System;
using System.Collections.Generic;

namespace DataSource
{
    public interface IFactoryConsumer
    {
        void LoadData(ref List<DataModel.Entity> lst, 
             NHibernate.ISession session);
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataModel;

namespace DataSource
{
    public class FactoryConsumer : DataSource.IFactoryConsumer
    {
        IDataFactory m_fac;

        public FactoryConsumer(IDataFactory fac) {
            m_fac = fac;
        }

        #region IFactoryConsumer Members

        void IFactoryConsumer.LoadData(ref List<Entity> lst, NHibernate.ISession session)
        {
            lst.AddRange(m_fac.GetData(session));
        }

        #endregion
    }
}

In the home controller I, perhaps not so wisely, renamed the existing data access function LoadDataFromFactory to demonstrate that it loads data directly from the IDataFactory, and created a new function LoadData that gets its data from a IFactoryConsumer.  Then I changed the caller to access both function, getting product data from the Factory Consumer, where Castle secretly and automatically figures out which factory to use, while still loading service data from the factory directly as before.

Config changes

To accomplish the above there had to be some changes to the configuration file. I specified that the Product Data factory has a ‘service’, which is, incidentally IDataFactory. Ahead of both factories I declared my factory consumer. As you can see, Castle cleverly figures out quite a few things on its own, like how to create my Factory Consumer with no more than two empty hands and, incidentally, a component just a line or two below in the web.config file that actually implements IDataFactory which is what it needs to call the constructor of the FactoryConsumer.

 

  <castle>
    <facilities>
      <facility id="loggingfacility" 
                type="Castle.Facilities.Logging.LoggingFacility, Castle.Facilities.Logging" 
                loggingApi="log4net" 
                configFile="logging.config" />
    </facilities>
    <components>
      <component id="ProductLoader" 
                 type="DataSource.FactoryConsumer, DataSource"  />
      <component id="ProductData" 
                 type="DataSource.ProductInfoFactory, DataSource"
                 service="DataSource.IDataFactory, DataSource"/>
      <component id="ServiceData" 
                 type="DataSource.ServiceInfoFactory, DataSource" />
    </components> 
  </castle>

 

Output changes

When you make the above changes to the source, rebuild and ‘play’, you will notice the following changes compared to the other source:

 

That’s right. Nothing. Exactly the same output is produced.

So, what was the point of all this you ask? Well, as you can see, I could easily move the ‘service’ tag in the config file and have the web page display service info only. We have lifted the dependency control right out of our lap and left it in the hands of the guy/gal who owns the config file. There are so many implications of this; everything from enabling completely changing to different data sources or services on the fly, making partial upgrades, moving from staging to production environments dynamically and so on.

The ASP.NET project

As the returning reader may have noticed I have used the Model-View-Controller framework for ASP.NET again and again in the few posts I have produced so far. This is because unlike the ASP.NET standard framework, the MVC framework allows and simplifies actual programming in lieu of VB3 style component hell. To show proof of my benevolent and magnanimous generosity, I have however decided to let go of my loathing for the standard ASP.NET setup and actually try to make something out of it, utilizing every bit of it just to see if it can be used for anything real.

Orientation

There is a plethora of Server Controls, at least one for every imaginable application known to man. The idea is that when you have a business problem you want to solve, you simply write <asp: in front of a general description of your problem. switch to Design view and edit the properties of your server control.

Example:

I would like to create a wizard that allows me to create a ASP.NET Forms user account… Let’s try it:

Hmm… that would mean…  ‘<asp:’ and then, let’s try .. ‘ CreateUserWizard />’ … Switch to design view… Woah!!!

This is just one example, but the amount of server controls  out there is limitless and you can watch your ViewState go from 0 – 60MB in seconds with ease, building your website with themeable data bound server controls fully integrated with your web.config.

I have seen people dismiss the MVC framework as it means ‘a move away from Server Controls back to spaghetti code’. I find this unfathomable. Server controls try to abstract away the fact that this the application runs on a web server which is inherently stateless. Through the use of ViewState and other constructs the server controls use a variety of dirty tricks behind the scenes to hide this basic fact from the confused developer. In practice however I have never seen a case where this abstraction has been successful and there have always been places in a web application that have deteriorated into near-ASP Classic monstrosities.

I have always put the blame for this squarely on the shoulders of the ASP.NET Server Control concept.  However, I have decided to actually put my money where my mouth is on this one and actually make a serious effort to build something usable out of a bucket of server controls and see if it can actually be done. For real. All the way. 

Example

I am going to build an application that uses the following aspects of the ASP.NET basic features:

  • ASP.NET Forms Authentication
  • Themes
  • Profiles
  • Wizard
  • DataGrid
  • GridView
  • DetailsView
  • DataGrid
  • MultiView
  • … any other controls that I find irresistibly disturbing

I have a useful scenario which I have been working with, however I will not release the details of this yet, and I will only briefly discuss the actual application. The point of this exercise is whether or not the controls are useful, how difficult they are to manage in a professional way and the amount of ugly code that is necessary to patch things up.  I  will go through this anxiety ridden journey on my own and spare you most of the details and only report back when I need to vent or when I, maybe, reach points of success. I do this so that I will reach a point where I can disrespect the ASP.NET framework with greater authority. I admit there is a risk I may come out on the other side a changed man, a born-again VB3 fanatic, touting opaque server logic, horribly leaky abstractions and other features as reigning supreme over so-called real programming, we never know.

IIS Security

While working on a project today I got a bit frustrated. Instead of having one security setting per node in the conceptual tree that a web server in effect is, thus allowing people to actually configure authorizations to the allow the least possible and still run the applications, there are six hundred and fifty nine separate places to configure access usually meaning that in the initial phase people run everything as Enterprise Administrators, from the web site identity down to the least possible scriptlet just to get something up on the screen when you test the app on your own box.  If you insist that ‘but we need to make the websites impossible to configure, otherwise there is no security’, at least provide me with a big fat ‘Make it so’ button that allows me to ensure that, say, an AD group that should be allowed to look at a web site, by me having pressed the Patrick Stewart-button while the group was selected, they would actually be able to see the web content without any error 500.x/ 403.x because a .config file had the wrong permission sets way back somewhere. I love low permission worker process identities, but please configure them automagically through the admin tools. The problem is other people and viruses messing with the websites, Making them impossible to configure isn’t exactly helping people to lower security settings. Just don’t leave the server open  for attacks in the first place so that other people than me get to configure my server and you’ll see that security will be just fine.

OF course, once I calmed down I realized there are ways of dealing with the frustration, especially with IIS7.0 and I should at least share this link.

Basic IIS7 troubleshooting

Castle Windsor and nHibernate in ASP.NET MVC

Years later after this post was originally written, things have improved – see updates.

I will in this post attempt to show how to make a simple DI scheme, access data through the nHibernate O/R-mapper, and present it in an ASP.NET MVC web site. I will present sample code and sample XML along the way and I have also bundled the Visual Studio solution and sample database in an easy-to-download Zip file. Work was greatly simplified by excellent sources, that are listed below

The Premise

The web site in this case is rudimentary to the power of three. It will display one list. On the start page. No clicking involved, just straight to the point.

The list will contain services and items. The point is to illustrate a need to uniformly treat information from two sources. In this case there are two tables in the same database, but conceptually you could have one piece of information in the ERP system and the other one in the CRM system, for instance.

The Domain Classes

The two types of data, Items and Services, are implemented in the POCO classes Item and Service. Both inheriting common properties from the POCO class Entity for the sake of me not having to write as much code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DataModel
{
    public class Entity
    {
        public virtual int Id { get; set; }
        public virtual string Description { get; set; }
        public virtual string Identifier { get; set; }
        public virtual double UnitPrice { get; set; }

    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DataModel
{
    public class Item : Entity
    {
        public virtual double Inventory { get; set; }

        public Item() {
        }

    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DataModel
{
    public class Service : Entity
    {
        public virtual double ExpectedDuration { get; set; }

        public Service() { 
        }
    }
}

As you can tell, the classes exposed to nHibernate  require a public default constructor. Properties must be public and virtual.

In SQL Server two tables are created, Item, Service and the common fields are inherited through Copy/Paste.

The Mapping

For this exercise I went with nHibernate 2.0.1. To use that at the same time with Castle Windsor you need to directly specify the NHibernate assembly of the correct version and avoid the 1.2 version shipped with Castle Project. To do this I simply chose the Browse tab under Add Reference… and pointed to the correct assembly. Be careful here to double check your assembly versions, because if there was a blooper reel to this blog you would have seen a clip of me trying to configure a 1.2 nHibernate assembly with 2.0 XML because I had taken the NHibernate reference at face value. <Canned laughter>

For each domain table I made a mapping file to map the assembly, namespace and class with the physical table and the individual fields with their corresponding properties. Very straightforward indeed. The files are named in the following manner: namespace.class.hbm.xml As you can plainly see, the properties inherited from the Entity class are mapped as if they belonged to the Item or Service classes directly. Below: DataModel.Item.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   namespace="DataModel"
                   assembly="DataModel">

  <class name="Item" table="Item">

    <id name="Id" column="Id" type="Int32">
      <generator class="identity"/>
    </id>

    <property name="Description"    column="Description"    type="String"/>
    <property name="Identifier"    column="Identifier"    type="String"/>
    <property name="UnitPrice"    column="UnitPrice"    type="Double"/>
    <property name="Inventory"    column="Inventory"    type="Double"/>

  </class>

  <query name="DataModel.Item.GetAll">
    <![CDATA[
    from DataModel.Item
  ]]>
  </query>

</hibernate-mapping>

 

In order to fetch a list of Items, the XML file contains a very simple query definition that simply requests every record from the table sans filter. As we take a look at the file containing the mapping against the Service table, we see very similar content:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   namespace="DataModel"
                   assembly="DataModel">

  <class name="Service" table="Service">

    <id name="Id" column="Id" type="Int32">
      <generator class="identity"/>
    </id>

    <property name="Description"    column="Description"    type="String"/>
    <property name="Identifier"    column="Identifier"    type="String"/>
    <property name="UnitPrice"    column="UnitPrice"    type="Double"/>
    <property name="ExpectedDuration"    column="ExpectedDuration"    type="Double"/>

  </class>
  <query name="DataModel.Service.GetAll">
    <![CDATA[
    from DataModel.Service
  ]]>
  </query>


</hibernate-mapping>

 

NHibernate requires Session state to be maintained. This is performed through the use of an Titmouse that maintains the connection across an entire IIS request. You could figure this code out on your own or follow my lead and find it online. The HttpModule is registered with the IIS  web.config and is thereafter managed automagically by the web server. A caveat I ran into was that you cannot just register modules willy nilly on a Vista machine, You have to command some authority over the applicationHost.config file and specifically allow the server or, rather, individual web sites to add modules on their own.

I have included an NHibernateHelper class with static methods to execute the queries that we defined in the XML files above. The helper class is quite accomplished in that it has built in paging and is very clean and easy to understand. It was written and conceived by a colleague of mine.

At this point we have:

  1. Created POCO classes that represent our domain information
  2. Created SQL Server tables that contain the information we wish to display
  3. Created mapping files to correlate between 1 and 2 and define queries for future use
  4. Set up Session state in NHibernate through the use of the IHttpModule interface
  5. Defeated the applicationHost.config issue
  6. Included helper functions to help us execute the queries defined in 3.

The IoC scenario

To illustrate Inversion of Control I chose a very simple example. The web site wants to display a list of stuff that you can buy, regardless of whether it’s goods or services, whether it’s stored in the database directly or catalogued in an ERP system somewhere.  In this extremely simple example, the Controller will itself call the data retrieval function and collect all data in a List<Entity>.

A more feature rich option would have been to create a class for the data retrieval function below and register it as a Castle component and then let Castle create the data retrieval function with the implementations for Services or Items already loaded. I may just do that in the future.

How is all this implemented you ask?

In the web.config file, two Castle.Windsor Components have been defined  Both of them return objects of the Entity class. One retrieves Items and the other retrieves Services. 

 <castle>
    <facilities>
      <facility id="loggingfacility" type="Castle.Facilities.Logging.LoggingFacility, Castle.Facilities.Logging" loggingApi="log4net" configFile="logging.config" />
    </facilities>
    <components>
      <component id="ProductData" type="DataSourceFacility.ProductInfoFactory, DataSourceFacility" />
      <component id="ServiceData" type="DataSourceFacility.ServiceInfoFactory, DataSourceFacility" />
    </components> 
  </castle>

In the Home controller in the website, both components are queried and the results go in a List<Entity> that is passed through to the HTML View and there indeed presented to the user.

As is plainly visible, the component names are daringly hard coded in the call to LoadData below.

        public ActionResult Index()
        {
            ViewData["Title"] = "Home Page";
            ViewData["Message"] = "Welcome to ASP.NET MVC!";

            List<Entity> l = new List<Entity> ();

            LoadData(ref l, @"ProductData");
            LoadData(ref l, @"ServiceData");

            ViewData["Collection"] = l;

            return View();
        }
            WindsorContainer container = new WindsorContainer(new XmlInterpreter());

        private void LoadData(ref List<Entity> lst, string provider)
        {
            DataSourceFacility.IDataFactory source = container.Resolve<DataSourceFacility.IDataFactory>(provider);
            lst.AddRange(source.GetData(NHibernateModule.CurrentSession));
        }

 

Where are we now?

  1. We have defined data access classes in a dedicated assembly. 
  2. These data access classes are registered as components in web.config
  3. The Castle Windsor dependency injection container thereafter activates the classes by name
  4. Data is collected from the two sources into one list ready to be displayed to the user.
The GUI

In closing I just want to mention the issues that came from going from Preview 3 to Beta on the ASP.NET MVC framework while writing this post. The HtmlHelper class no longer has an ActionLink so I had to review my Master Page and change to an Ajax.ActionLink.Of course, the RenderPartial function was not available anymore either so the login box had to go.

After all this, 5 minutes after I close Visual Studio for the last time, Scott Guthrie reveals the first release candidate and you’ll be in for a new set of challenges porting this website to the RC1 ASP.NET MVC framework.

The conclusion

The Castle Windsor dependency injection container and NHibernate work just fine together as long as the version issues are kept at bay. NHibernate deals well with inheritance, but the ‘all properties must be virtual’ and ‘there must be a public default constructor’-bit destroys the purity of the O/R concept.

3 Customer Support: -1

Due to my recent foray into the beta OS lifestyle I had the displeasure of finding out that the 3 Connect Huawei 220 Turbo 3G connection software provided by the telco that goes by the long-winded name of 3, does not in fact install post upgrade. Or, it installs, but does not execute.

I placed a call to the customer support hotline and after explaining to the 1st line support that yes, Windows 7 is newer than Vista, he would consult with a colleague and get back to me. I waited patiently for the inevitable “Dude, you’re running a beta OS, can you say: NOT SUPPORTED?”, but instead, imagine my surprise, the guy comes back on the line saying “I talked to our technicians and they are aware that regrettably, the software does not work on Windows 7 yet, but we are working to solve the problem presently”. Practical difference for me? None. Except you feel a lot better when people give the impression of caring. This bumps 3 tech support from 0 to –1.

Of course, I would not be this magnanimous and benevolent if had been kept from using the wireless broadband entirely. A windows dialup connectiion could access the modem and create a connection, so in the end I could make do just fine without the 3Connect software

Quick Answers –1 or 0

So you want to know what is hot or not? You want to know what to think on a variety of subjects but you cannot really be bothered with getting to know the issues first hand? Search no further:

Windows 7: –1

A solid, dependable operating system despite being a beta. Sure, some websites look upon your HTTP_USER_AGENT suspiciously, thinking that NT6.1 is no an OS they can support, but that is an issue that can be remedied in Firefox among others through simply spoofing the USER_AGENT-string. Problem free upgrades and installs are reported, stuff just keeps on working. Uneventful and boring, just as you want them. Lots of small details that gets you hooked right away strictly because of the improvements to the user experience, the improved keyboard shortcuts, the new structure in the control panel, the way dialup and VPN-connections are activated and deactivated from the taskbar, the new taskbar in general.

Introduction

This blog is a deposit for my ideas and ramblings. I intend to blog occasionally. In English. It will be loosely coupled to my work as a .NET consultant at Dotway. Not that much gossip. Neither sex or drugs but perhaps the odd bit of rock’n’roll.