I digg kicking that link into the zone of votes

by Ben Hart 26. November 2008 14:14

For years I've been aware of DotNetKicks (I believe the stream of consciousness at the time was, "Jeepers,  this guy's put all this effort into a blog post, and someone's kicked him. Oh, it's a good thing. Oh, this site aggregates .net related links, and spreads those that are popular. That's cool!")

I only really got into it recently (shamefacedly, most likely since I started coveting those kicks as a blogger myself) and I must confess it's a struggle to keep up. What with the blog roll, the mailing lists I monitor, occasional forum posting, required daily research, links sent around the office, having more required reading so well shared via DNK can be overwhelming. Especially considering I've got to get some actual work in too.

Keeping up to date with trends and continuous improvement is an essential part of my job, so I make the time for most of it. I do sometimes wish I'd chosen a less progressive profession, though. Something like Phrenology, those guys haven't had any advances for ages...

The nifty links BlogEngine.NET had by default (note to self: one of these days I must customise this thing further) exposed me to DZone ("Oh great, more fresh links for developers"), previously unknown to me probably because they don't do trackbacks. DZone is awesome, the most polished of interfaces, and a great, wide variety of content. You can even be a bitch, and vote down. Nice.

Then today for the first time I noticed some other trackbacks appearing in blogs I read. Suddenly I noticed that people were being voted (great) on the Web Development Community, and linked on DotNetLinks. Not sure how long they've been around, but they're new to me.

Oh my. Come on guys, some of us are desperately trying to do some work over here :)

In the meantime though, I think I'll publish this to all those sites I've mentioned. Maybe I'll even discover some more...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Blogging | Life | Software Development

ASP.NET MVC SelectList selectedValue Gotcha

by Ben Hart 24. November 2008 13:14

A recent post from Ayende was declaring a another bug in ASP.NET MVC, specifically referring to a select not rendering with the option selected. I remembered that we had had some issues some time ago, and had made our own helper to render selects, and took the opportunity to see whether we had made the same incorrect assumption - passing in the whole object, when only the value field was required.

I think we might have, but chatting to the team some other problems were experienced. It seemed the selected value was working in some situations, but not all. To keep as simple as possible, I used a test class similar to Ayende's:

public class IdName
{
    public int Id { get; set; }
    public string Name { get; set; }
}

And built a SelectList as duly instructed by the commentators on the post:

var list = new[] 
{   
    new IdName { Id = 1, Name = "Name1" }, 
    new IdName { Id = 2, Name = "Name2" }, 
    new IdName { Id = 3, Name = "Name3" } 
};
var selectList = new SelectList(list, "Id", "Name", 2);
ViewData["TestClasses"] = selectList;

Using the following extension method on the view

Html.DropDownList("TestClass", (SelectList)ViewData["TestClasses"])

this all works as expected:

<select id="TestClass" name="TestClass">
    <option value="1">Name1</option>
    <option selected="selected" value="2">Name2</option>
    <option value="3">Name3</option>
</select>

I noticed, though, that this was not working for all our views. Despite exactly the same pattern, many of our views weren't rendering the selected attribute.

At some point long ago we built our own binding framework that reflect items and passes found values through. Thus often we have a referenced object which is passed through to the view, and we there have a few helpers that get id's and appropriate 'names'. At the time this seemed fine, in retrospect we've painted ourselves into a corner. If we modified the above snippet to something along the lines of:

var list = new[] 
{   
    new IdName { Id = 1, Name = "Name1" }, 
    new IdName { Id = 2, Name = "Name2" }, 
    new IdName { Id = 3, Name = "Name3" } 
};
var selectList = new SelectList(list, "Id", "Name", 2);
ViewData["TestClasses"] = selectList;
ViewData["TestClass"] = 3;

The select does not render with the option passed in to the SelectList as the selectedValue, but rather uses what is found in ViewData with the same name as the select.

<select id="TestClass" name="TestClass">
    <option value="1">Name1</option>
    <option value="2">Name2</option>
    <option selected="selected" value="3">Name3</option>
</select>

If what is in ViewData does not correspond to the value, nothing is selected. I played around with this for much longer than I should have before investigating the beta source, which has the following block in SelectExtensions.SelectInternal():

// If we haven't already used ViewData to get the entire list of items then we need to
// use the ViewData-supplied value before using the parameter-supplied value.
if (!usedViewData) {
    object defaultValue;
    if (htmlHelper.ViewData.TryGetValue(name, out defaultValue)) {
        selectList = new MultiSelectList(selectList.Items, selectList.DataValueField, selectList.DataTextField,
            (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue });
    }
}

The RenderDropDown above eventually calls this method passing in false for usedViewData, and as such the above is always executed. Thus no matter what is passed in to the selectedValue of the SelectList, it will always be overridden by any object in ViewData with the same name as the select.

Now that I understand what's happening it's a little easier to bear. I also acknowledge that one could (even should) adopt a practice of ensuring that the object in ViewData with the same key as the desired name of a select should contain value to be marked selected.

But still, if I've gone to the effort to set the selectedValue in the SelectList, I'd prefer it to take precedence.

Technorati Tags:

Currently rated 4.3 by 6 people

  • Currently 4.333333/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

ASP.NET MVC

Dependency Inversion for Dummies: Unity and StructureMap

by Ben Hart 20. November 2008 14:55

This is it. The moment you've been waiting for. The series that has you periodically checking back to see if there is another instalment continues (since the frequency of my posts has you questioning whether the feed is working). Dependency Inversion for Dummies is back...

Previously...

When we started on this journey, early on, we were empowered with the knowledge of how insidious dependencies can cripple an application's ability to change. Despite this alarming revelation, in the spirit of developers knowing that the time of failed software projects must change, we read on. Yes we can.

Rather than despair at this new knowledge we considered that a simple means to reduce this restrictive coupling is constructor injection. We struggled through references to teen chick-rock, arrogant comparisons to blockbuster TV-Series, bad examples, always seeking this better way. Yes we can.

When we then discovered that inverting our dependencies can make for more work in object creation, rather than walking away and dismissing this as a fad, we took the high road to find out how centralising object creation can help. Yes we can.

When all seemed lost, when the temptation to ignore the breakthroughs of those that came before us began to overwhelm our new sensibilities, we learned that factories or service locators are not only simple concepts, but remarkably easy to implement and use. Yes we can.

And, when promises of a follow-up were not kept, and when a week became a fortnight, a month, more, did we lose faith in the value of this blog, or did we stand up, with resolve and patience, and understand that Ben Hart is an African, and that in Africa, we work on African Time?

Unity and StructureMapYes we did

Today we use some tools, and compare them with the simplest of all requirements. This will not be a comparison of features, nor an evaluation of any sort. Don't leave this settled on an IoC container without investigating them yourself. Take a look at least at Autofac, Ninject, Windsor and Spring.NET before you make up your mind. Choose the one that works for you, while all similar in the basics, they all bring something different to the party (some bring the whole bar!).

Today we're just going to look at the tool I use against the one released by Microsoft. The Apache 2 OSS against the MPL. The industry veteran against the newcomer. Hulk Hogan against Toa.

 [While I generally don't care much for what people think of me, the thought that anyone might assume that I knew who Toa was before this blog post is too much to bear. This was merely the first image result that had an oldie of WWF (in my time, the kids call it WWE these days) with a newcomer. That's my story, and I'm sticking to it.]

Where's the code?

Remember last time we had centralised object creation into a simple service locator. It wasn't all that pretty. It was called by a simple console application that requested an instance of the ITagService in order to retrieve tags. The whole application fits into this tiny box:

class Program
{
    static void Main(string[] args)
    {
        ITagService tagService = ServiceLocator.GetInstance<ITagService>();
        foreach (string tag in tagService.GetUniqueTags())
        {
            Console.WriteLine(tag);
        }
        Console.ReadLine();
    }
}
 
public static class ServiceLocator
{
    public static T GetInstance<T>()
    {
        return (T)GetInstance(typeof(T));
    }
    public static object GetInstance(Type type)
    {
        return GetInstance(type.Name);
    }
    public static object GetInstance(string name)
    {
        switch (name)
        {
            case "ITagService":
                return new UniqueTagService(new TagDatabase());
        }
        throw new ArgumentOutOfRangeException("name", string.Format("{0} is not a registered type.", name));
    }
}
 
public interface ITagService
{
    IList<string> GetUniqueTags();
    int TagCount();
}
 
public class UniqueTagService : ITagService
{
    private ITagData _db;
 
    public UniqueTagService(ITagData database)
    {
        _db = database;
    }
 
    public IList<string> GetUniqueTags()
    {
        return new List<string>(_db.GetTags().Distinct());
    }
 
    public int TagCount()
    {
        return _db.GetTags().Length;
    }
}
 
public interface ITagData
{
    string[] GetTags();
}
 
public class TagDatabase : ITagData
{
    private string[] _tags = new[] { "Word1", "Word2", "Word3", "Word1" };
 
    public string[] GetTags()
    {
        return _tags;
    }
}

Rather than change much else, we're simply going to extend the service locator to use the new tools in our belt. Notice that our client code is only calling the generic GetInstance<T> method, the overloads were simply to confuse you. So, without any further ado, let's meet our contestants.

First into the ring: the drum beater, the system cheater, the broadcaster, the drummer... can a get a shout out fooooooorrrrrrrr.......

StructureMap

First up you'll need to download the latest binaries from the sourceforge site and add a reference to StructureMap.dll. While there are other means to configure, the easiest has to be the internal dsl. The simplest means to use this is the creation of a registry file, and the override of the configure() method.

public class MyRegistry : Registry
{
    protected override void configure()
    {
        ForRequestedType<ITagService>().TheDefaultIsConcreteType<UniqueTagService>();
        ForRequestedType<ITagData>().TheDefaultIsConcreteType<TagDatabase>();
    }
}

All we've really done here is mapped the implementation we desire to the type that will be requested. Next thing is to let StructureMap know about the registry, and wire it into our service locator.

public static class ServiceLocator
{
    static ServiceLocator()
    {
        ObjectFactory.Initialize(c => c.AddRegistry(new MyRegistry()));
    }
    public static T GetInstance<T>()
    {
        return ObjectFactory.GetInstance<T>();
    }
}

For simplicities sake I've called ObjectFactory.Initialize() from the static constructor of our already static service locator. You'd generally only want to call this once in an application, and this achieves this. Note the lambda adds the registry to the object factory, and that our GetInstance<T> defers to the factory.  That's all that's required. (Note also that having the service locator wrapping the IoC container is not something I'd recommend, rather just a means to continue without changing any more code.)

More astute readers may wonder HTF this works? All we've requested is the ITagService. ITagService has a dependency to ITagData, previously we had to instantiate the TagDataBase and pass it in. WTF is going on here?

That, my friends, is the beauty of auto-wiring. StructureMap takes it upon itself to examine the requested type for dependencies, and creates and passes those in when requested. Just don't forget to say thank you.

Well that was pretty simple. Now the one I've been l've been waiting for. The one I've been meaning to look at for ages. The one that at first appalled me as a senseless waste of resources when the existing alternatives were so plentiful. The one that will likely be the most adopted despite its relative youth. Can I get a whoop-whoop foooooorrrrrrr.....

Unity Application Block

First up you need to track down the download of the binaries. If StructureMap is a little modest with its download link, Unity can only be described as coy. Following the links you'll likely end up here. Install the msi, and add a reference to Microsoft.Practices.Unity.dll.

The container in Unity is called UnityContainer (ObjectFactory in StructureMap provides static methods that wrap the Container, but it's still there). Unity is a breeze to get started with. All we need to do is create the container in our service locator, and register the types.

public static class ServiceLocator
{
    private static IUnityContainer _container;
 
    static ServiceLocator()
    {
        _container = new UnityContainer();
        _container.RegisterType<ITagService, UniqueTagService>();
        _container.RegisterType<ITagData, TagDatabase>();
    }
 
    public static T GetInstance<T>()
    {
        return _container.Resolve<T>();
    }
}

F*ck me, that was easy. Finding the download took longer! So easy that I had to find a similar implementation in StructureMap...

public static class ServiceLocator
{
    private static Container _container;
    static ServiceLocator()
    {
        _container = new Container(x => 
        { 
            x.ForRequestedType<ITagService>().TheDefaultIsConcreteType<UniqueTagService>();
            x.ForRequestedType<ITagData>().TheDefaultIsConcreteType<TagDatabase>();
        });
    }
    public static T GetInstance<T>()
    {
        return _container.GetInstance<T>();
    }
}

Here we're accessing the container directly, configured through the constructor. A few more lines of code, but as simple. I'll likely stick to using registries, but options are useful. (Note this would have taken me longer to discover if not for Jeremy D. Miller's epic weekend series of posts documenting StructureMap 2.5, this one in particular.)

Wrapping up

Remember that the above is the simplest of uses for a IoC container, but already I hope the value is clear. Next time we'll look at some of the more advanced uses, and, since I've enjoyed my introduction to Unity, maybe even get to know Autofac a little better...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , ,

C# | Design Patterns

NHibernate Starter Kit Enhanced

by Ben Hart 15. November 2008 11:32

I've spent some time today enhancing the NHibernate Starter Kit. My previous post describes what the kit is about in greater detail, so please give it a read. To recap, though, the kit is intended to be a means to get started with NHibernate within minutes. Once installed you'll have a new project template within Visual Studio that contains all NHibernate binaries, a simple domain project demonstrating some common mappings, a console application that generates a database and some test data, and some example unit tests that tie it all together.

It is not intended to be a demonstration of advanced features of NHibernate, nor a demonstration of any best practices. Once this kit has got you started there are many better resources out there to teach you those. I've intentionally kept things as simple as possible.

A common objection to NHibernate is that it's too complicated. I want this kit to prove that objection wrong.

So what's changed?

I wasn't too delighted about the PersistentEntity class to begin with. I didn't want anyone to assume that this was a requirement, nor did I want to have to create an enterprise ready class like that found in the S#arp Architecture. Having a base class for entities in NHibernate does help though, so I tried to keep it as simple as possible.

Unfortunately my class had some issues that would result in confusing bugs. The previous override of object.Equals() looked more or less like this:

PersistentEntity other = obj as PersistentEntity;
 
if (this == other)
{
    return true;
}
 
if (other == null)
{
    return false;
}
 
return this.Id == other.Id;

This was problematic since two transient entities (newly created, and not yet saved to the database) would evaluate as equal. The id of the entity is only assigned once the object has been saved, and thus that last statement would be true for any two unsaved entities! "Thanks for that great starter kit, Ben..."

The next problem was with the naive override of object.GetHashCode():

public override int GetHashCode()
{
    return Id;
}

This works for many situations, but falls flat in others. Firstly (and most seriously), this means that two transient entities will have the same hash code, and once saved they will suddenly have a different hash! Secondly persistent entities of different types have the same id, they too will both have the same hash code.

The default mapping used a hilo generator for id's. In a nutshell, hilo uses a sequence of unique ids to assign to entities as they are saved. The sequence is tracked using a separate table in the database, and this results in every entity being given a unique id. I like hilo since it gives the flexibility of guids (don't have to worry about the autoincrement quirks of various databases, for one, nor the constraint of hitting the database to get an id), with the usability of integers (if you ever need to manage the database by hand integers are a lot easier to work with than guids). If anyone changed the mapping away from hilo to one that gave different types the same id, GetHashCode() would start causing problems.

So I've reluctantly changed the id of the base class from an integer to an guid. PersistentEntity now has the following implementations (courtesy of Gabriel Schenker's good article up on nhforge):

public override bool Equals(object obj)
{
    PersistentEntity other = obj as PersistentEntity;
 
    if (this == other)
    {
        return true;
    }
 
    if (other == null)
    {
        return false;
    }
    //Transient entities will both have the same id, and as such we must check for reference equality.
    if (this.Id == Guid.Empty || other.Id == Guid.Empty)
    {
        return ReferenceEquals(this, other);
    }
 
    return this.Id == other.Id;
}
 
public override int GetHashCode()
{
    // Once we have a hash code we'll never change it
    if (_oldHashCode.HasValue)
    {
        return _oldHashCode.Value;
    }
 
    // When this instance is transient, we use the base GetHashCode()
    // and remember it, so an instance can NEVER change its hash code.
    if (Id == Guid.Empty)
    {
        _oldHashCode = base.GetHashCode();
        return _oldHashCode.Value;
    }
 
    return Id.GetHashCode();
}

This was the right choice. It's kept PersistentEntity as simple as possible, at the small cost of making some manual DBA work a little harder.

Some more mappings

In the interests of getting started more quickly, I've added some more entities and mappings to the starter kit.

Domain

I've thrown together the classes as seen on the left. Again nothing fancy, just a means to illustrate common mappings.

A venue has a one-to-many to courses, which is mapped to cascade="all".

A course has a many-to-one back to the venue, and well as a many-to-many to the students in the course.

A student has a many-to-many to courses.

There are some simple tests that verify some of this behaviour. By no means conclusive, but enough to get started with.

Picking up the theme yet?

 

I've also realised that the template will not work without some effort in Visual Studio 2005. I might address this in future, but for now have limited the vsi to only install to Visual Studio 2008.

To remove the previous version, simply delete the old NHibernateStarterKit.zip file from "[My Documents]\Visual Studio 2008\Templates\ProjectTemplates\Visual C#", and the corresponding 2005 if applicable.

As before, if you have any suggestions or problems, please contact me any which way you please.

NHibernateStarterKit.vsi (738.18 kb)

 

Technorati Tags: ,,,

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

C# | NHibernate

Generic Variance Baby!

by Ben Hart 13. November 2008 15:40

I've been pretty busy lately. The day job is getting interesting, as are a few side projects. A lot has happened the last few weeks, both in my world, and the larger .NET'o'sphere. I haven't had much time to write to this blog, but I've made an effort to keep up with others.

What I'm still most excited by (yes, it's been a few weeks of heightened heart-rate) is the introduction of generic variance in C#. I don't care to admit how many times I've written something along the lines of the following:

public void DoSomething()
{
    IList<Child> children = new List<Child>();
    IList<Parent> parents = children;
}
class Parent{}
class Child : Parent{}

The above invalidity is obvious (after the first time, at least), but more subtle variations continue to catch me (lambdas spring to mind). It seems so intuitive to be able to assign a generic type of a subclass to that of a superclass. I've occasionally refactored to a point relying on something along these lines, before pulling up the handbrake (or is that the shift to reverse?) when the compiler reminds me it's not valid.

GVAvatarBut no longer. Well, at least, soon no longer... C# 4.0 introduces generic variance.

I'm not going to add anything to what's already been written. My only contribution is my little friend on the left here - lovingly created to celebrate the occasion. He represents the wonderful diversity in code that will soon be possible. (Except the t-shirt. That's chosen because a friend of mine played with My Little Ponies as a boy, so that's for him.)

If you want to learn more about generic variance, and be casually able to drop the terms covariant and contravariant into the standup tomorrow morning, Nate Kohari has a great summary in this post. Alternatively, download the CTP of VS2010, and shake up that invariance...

Technorati Tags: ,,,,

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

.NET | C#

SPAM!!!

by Ben Hart 11. November 2008 15:19

I feel like my blog has come of age.

While I've been too busy on personal life to write even so much as an apology post, some sneaky bot managed to get some medication advertising as a comment on an old post.

Nice. And here I was thinking my readers were getting a rise from my good writing alone...

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Blogging

Repeat after me, "check yourself before giving bad advice"

by Ben Hart 3. November 2008 12:59

Some time ago I started to give some advice to someone on the alt.net mailing list regarding converting an ASP.NET 1.1 web site to ASP.NET 2.0. I'd gone through this some time before that, and thought I could share some pointers. Another reader had suggested he skip 2.0, and bring it into 3.5, which made sense.

I don't really use the Web Site template (or is it a model?). Having come from the early days, Web Application was a lot more familiar, and I (thankfully) bridged into 2.0 after the initial release of the separate installer. I've since played around a little with the Web Site, but the Web Application will remain the only one I'd choose. Not sure if that's resistance to change (since I've never really taken the time to understand the real differences) or just my natural knack to pick the best model.

To cut a long story short, I couldn't understand the problems he was having converting the now Web Site (he'd rolled into VS 2008) into a Web Application. Dude, just right-click the site, and select "Convert to Web Application". No, really, dude, while it was a while ago, I've been through this. Just right-click the site, and select "Convert to Web Application". This carried on for a few more mails, before I presumed he'd finally seen the context menu item. It turns out his silence was more likely his giving up in frustration (or disgust).

I'm currently playing around with the Flixon site generator (which has a home elsewhere, the forum announcement seems to pip it in Google page rank, though), which generates a ASP.NET Web Site. Being more comfortable with Web Applications (and not wanting to learn how to reference Web Site code from a separate assembly for testing), I thought I'd just convert it to a Web Application. So just right-click, and select "Convert to Web Application". Hmm. Ok. Just right-click and select "Convert to Web Application". Hmmmmmmmm, that's weird. That option doesn't exist.

Turns out you can only convert a Web Application to a Web Application (as ridiculous as that might sound). The first step is to copy and paste all files from the Web Site to a freshly created Web Application. The rest of the steps are best described by Mohamed Meligy in this post. I think (but I'm not certain) that the same applies to 2.0, but who knows.

Sorry about the bad advice, guy. Next time I promise I'll check before harping on.

Technorati Tags: ,

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

.NET | ASP.NET

IEC Website WTF

by Ben Hart 2. November 2008 08:02

Here in sunny South Africa we're also gearing up for elections. Granted, not quite with the international significance as those over in the US, but it could be argued that my local government is just as likely to affect my day to day existence.

I'm obviously registered as a voter, but I wanted to check on Friday where, having recently moved district. Conveniently our local Independent Electoral Commission has a site you can enter your details, and check your registration status. I popped on over, and got this message:

IECHome

I haven't seen that for quite some time. Brought me right back to the turn of the millennium. It's clearly been updated recently (notice the mention of Chrome), but hell's teeth. I luckily use windows and have the option of IE (in fairness, they do mention IE 4 and greater, so in theory some adventurous mac users could have a go at it). But we're in a country whose government has openly embraced open source software. We're the birthplace and oftentimes home of he who is called Mark, arguably the one most likely to take Linux to the masses.

I took a look at the output html, and, in and amongst all the scary ASP.NET-and-Web-Forms-Designer-bastard-child HTML I think I found the reason non-IE browsers are not supported, called on load of the body:

<script language="vbscript"> 
Sub ShowMsg()
        
    if len(trim("")) > 1 then 
        msgbox("")
    end if 
    
    
    
End sub 
</script>

Now I'm no expert in vbscript (I missed that bus, and its route seems to have been cancelled), but my powers of deduction tell me that this one doesn't do much. Did anyone think to check the output html? Did anyone peruse the code that resulted in this? Perhaps a code review is too much to ask for, but having a developer on the team who leaves this in all the way to production is more a liability than an asset.

Come on guys, sort it out. This is important. I'm happy to lend a hand - drop me a line, I'll happily donate a few hours a week.

Technorati Tags:

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

.NET | Life | South Africa

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

About me...

I'm a passionate .NET developer, with C# my language of choice. I've been at it for a number of years now, and enjoy that I'll never shake the feeling I'm just starting out.

I love software, and I love building it even more. I love knowing that my work facilitates others', and that one line of code at a time, we're increasing our capability.

More...



Page List