Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Derik Whittaker

Thoughts on Software Development, .Net, OOP, Design Patterns and all things cool

August 2008 - Posts

  • Asp.Net RenderPartial Exception - CS1502

    If you are trying to use the HTML Helper RenderPartial and you received the following error:

    CS1502: The best overloaded method match for 'System.IO.TextWriter.Write(char)' has some invalid arguments error

    do worry, you are not alone.  When I was trying to upgrade DimeCasts.Net to Preview 5 I was getting this error.  What was really odd, was that the exception and stack trace did not really make sense.  It was not till I read Brad Wilson's blog did I realize what the issue was.

    Take a look at the following code:

    <%= Html.RenderPartial("somecontrol.ascx",  SomeDataEntity )  %>

    What you will notice is that the code above has an = sign in the markup.  I left this because I converted this code from Html.RenderUserControl which needed the '=' as it returned a string.  Since RenderPartial is void method you do NOT NEED the '='.

    Try removing the '=' sign and see if your issue goes away.

    The correct code would be:

    <% Html.RenderPartial("somecontrol.ascx",  SomeDataEntity )  %>

    Hope this helps someone else.

    Till next time,

    [----- Remember to check out DimeCasts.Net -----]

  • ASP.Net MVC Drop 5 has been released.

    Looks like Scott Gu and company put out drop 5 of their MVC Framework.  You can grab the latest drop from CodePlex.

    From taking a quick look at the Release Notes

    New Features

    • Various Controller and Filter Improvements
      • Removed the ActionMethod property from the filters
      • Add an IActionInvoker interface for release the controller class from having first hand knowledge of the ActionInvoker
    • Added various HelperMethod improvements
    • Added the ability to register your view engine globally
    • Modified the IViewEngine to add a RenderPartial for rendering partial views

    Breaking Changes

    • Changed the IViewEngine interface
    • Modified some of the HTML Helper methods
    • -- UPDATED -- All referenced MVC assemblies are now versioned 3.5.xxx.  You will need to update your web config correctly to get the site to work again.

    Unannounced Changes

    It looks like that they removed the sealed keyword from many of the Attributes such as HandleErrorAttribute, AuthorizeAttribute and various other existing Attributes. 

    However, looks like many of the other attributes (some new, some not) such as AcceptVerbsAttribute, ModelBinderAttribute and NonActionAttribute are still marked as sealed.  Guys, please unseal all your stuff.  If you have a very, very, very valid reason then fine seal them.  But if not, let developers loose and unseal them.

    I am looking forward to upgrading Dimecasts.net to Preview 5 in the coming days.

    Till next time,

    [----- Remember to check out DimeCasts.Net -----]

  • Adventures of adding YahooUI (YUI) to a MVC Site

    I decided that I wanted to give the YahooUI (YUI) framework/library a go recently.  My first task was to get a few of my data listing pages on Dimecasts.net to use the DataTable Control from YUI.  Having never used the library I was not sure what I was in for, but for once (ok, maybe a bit of an exaggeration) I was flooded with TOO much documentation.  With a bit help from Chris Sutton I was able to get a pretty nice datatable up an running in a pretty short period of time.

    Below what I needed to do in order to get the grid running (check here to see a working copy).

    1. Create the controller action that would return the data

      public JsonResult GetTopViewedItems()
      {
      	// CastsService is my call to the service layer
      	var items = CastsService.GetMostViewedEpisodes();
      	var jsonResult = Json( items );
      
      	return jsonResult;
      }
      


      Here I have decided to use the JsonResult ActionResult that is part of the ASP.Net MVC Project because it will take care of turning my object model into well formatted Json.
    2. Adding the place holder Div on my page where I wanted the data to go.

      <div id="items"/>
      

    3. Adding all the correct .js includes that are needed (and there are a ton)

      	
      // as you can see there are a ton that are needed.
      <script src="../../Content/YahooUI/yahoo/yahoo-min.js" type="text/javascript"/>
      <script src="../../Content/YahooUI/yahoo-dom-event/yahoo-dom-event.js" type="text/javascript"/>
      <script src="../../Content/YahooUI/element/element-beta-min.js" type="text/javascript"/>
      <script src="../../Content/YahooUI/event/event-min.js" type="text/javascript"/>
      <script src="../../Content/YahooUI/json/json-min.js" type="text/javascript"/>
      <script src="../../Content/YahooUI/connection/connection-min.js" type="text/javascript"/>
      <script src="../../Content/YahooUI/datasource/datasource-beta-min.js" type="text/javascript"/>
      <script src="../../Content/YahooUI/datatable/datatable-beta-min.js" type="text/javascript"/>
      <script src="../../Content/YahooUI/yuiloader/yuiloader-beta-min.js" type="text/javascript"/>
      
      


    4. Adding the correct YUI code in my in order to get and load my data.

              
      YAHOO.util.Event.addListener(window, "load", function() {
                         
      	// Add the custom formatter to the shortcuts 
              YAHOO.widget.DataTable.Formatter.myCustom = this.myCustomFormatter;    
      		var myColumnDefs = [                    
                          {key:"EpisodeNumber"},
                          {key:"Name"}, 
                          {key:"EpisodeDate"},
                          {key:"Count"}
                      ];
      
                      this.myDataSource = new YAHOO.util.DataSource("/Casts/GetTopViewedItems/");
                      this.myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
                      this.myDataSource.responseSchema = { 
                      fields: [{key:"EpisodeNumber"},
                                  {key:"Name"},
                                  {key:"EpisodeDate"},
                                  {key:"Count"}
                               ] };
      
                      this.myDataTable = new YAHOO.widget.DataTable("items", myColumnDefs, this.myDataSource, {});                             
                      
      });
      
      


      There are a few key points to pay attention to here
      1. I am telling the YUI library to call my controller action based on the provided route.
      2. I have set the responseType to TYPE_JSON, there are multiple types that this be set to
      3. I am calling this script on the page load.

     

    In the future I play to add skinning to the site as well as more async calls for things like the comment submission as well as data loading.  Expect more posts in the future.

    I hope this helps someone else get starting with YUI.  And remember to check out the YUI site as there are TONs of great examples and resources.

    Till next time,

    [----- Remember to check out DimeCasts.Net -----]

  • Setting up IoC/DI for your Controllers in ASP.Net MVC

    One of the really great things about the ASP.Net MVC framework is how extendable it is.  One area of extension is in the area of controller creation.  The framework allows you to replace the default ControllerFactory with your own factory and because of this we can incorporate Inversion of Control/Dependency Injection (IoC/DI) into our controller.

    Setting up our project for this is very simple and requires very little code. 

    1) Creating our IoCControllerFactory
    We need to create a new factory that will replace the default factory used by the MVC framework.

        public class IoCControllerFactory : DefaultControllerFactory 
        {
            protected override IController GetControllerInstance(Type controllerType)
            {
                // if you need more robust logic, add it now
                return (Controller) ObjectFactory.GetInstance( controllerType );
            }
        }
    

    2) Overriding the default ControllerFactory
    In order to use our custom factory, we need to set it to the default factory via our Global.asax file.  This logic should be put into Application_Start() method

    ControllerBuilder.Current.SetControllerFactory( new IoCControllerFactory() );
    
    

     

    3) Setting up our IoC/DI container
    In order to have StructureMap work we need to wire up all of our dependencies.  This could be done here inside (directly) our Global.asax file, but I would suggest putting it into its own class that is just called via the Application_Start() method

    StructureMapConfiguration.ForRequestedType<ISomeUsefulService>>().
                    TheDefaultIsConcreteType<SomeUsefulService>();
    

    The ISomeUsefullService and SomeUsefulService classes are your own classes that will be injected into our controller.

    4) Modifying our Controllers for IoC/DI
    We now need to modify our controllers to accept the various dependences that will be injected.

           public HomeController( ISomeUsefulService someUsefulService)
            {
                SomeUsefulService = someUsefulService;
            }
    

    There you go, it is pretty easy and simply to setup an MVC web project to use IoC/DI in its controllers.

    Till next time,

    [----- Remember to check out DimeCasts.Net -----]

  • Contextual Binding with StructureMap 2.5

    What is Contextual Binding?
    Contextual Binding is the ability to switch out different concrete implementations of a service (i.e. class) at runtime depending on the context in which they are used.

    One really cool thing about StructureMap is that it is very flexible.  Most times there are multiple ways to accomplish the same goal.  The reason for this is because everyone's needs are different and the tool takes this into account.

    There are 2 (at least 2, maybe more :) ) ways that we can perform contextual binding with StructureMap.

    Context Setup - The classes we will be using
    We will be creating a 'consumer' who likes to consumer soda.  The type of soda that the consumer will drink will be injected at runtime via StructureMap and we will swap the soda out at runtime with contextual binding

    Consumer Class - The class that consumes Soda

        public class Consumer
        {
            public Consumer(ISoda soda)
            {
                Soda = soda;
            }
    
            public string WhatTypeOfSodaAreYouDrinking()
            {
                return Soda.Name;
            }
    
            public Int32 HowManyCaloriesDoYouHave()
            {
                return Soda.Calories;
            }
    
            public ISoda Soda { get; set; }
        }
    

    ISoda Interface - The contract for our soda objects

        public interface ISoda
        {
            string Name { get;}
            Int32 Calories { get; }
        }
    

    DrPepper Class - An implementation of ISoda

        public class DrPepper : ISoda {
            public string Name { get { return "DrPepper"; } }
            public int Calories { get { return 250; } }
        }
    

    DietCoke Class - An implementation of ISoda

        public class DietCoke : ISoda
        {
            public string Name { get { return "Diet Coke"; } }
            public Int32 Calories { get { return 99; } }
        }
    

    Setting up StructureMap to know about the various classes

    StructureMapConfiguration.ForRequestedType<consumer>().AddConcreteType<consumer>();
    StructureMapConfiguration.AddInstanceOf<ISoda>().UsingConcreteType<DrPepper>().WithName( "DrPepper" );
    StructureMapConfiguration.AddInstanceOf<ISoda>().UsingConcreteType<DietCoke>().WithName("DietCoke");
    

    Setting the Default Instance on the fly:

    If you only need/want to swap out a single class at runtime the simplest way may be to just change the instance on the fly. 

    The code below will show how to do that.

    ObjectFactory.SetDefaultInstanceName<ISoda>( "DietCoke" );
    var consumer = ObjectFactory.GetInstance<Consumer>();
    
    // we now should have a consumer with an instance of DietCoke
    

    Using Profiles:

    A profile in StructureMap is basically a configuration group that allows you to prewire which types you would like to use for various contracts ahead of time.  By using a contract you can swap out many concrete types with a single line of code.

    The code below will show how to setup a profile as well as how to use that profile.

    Creating the profiles

    ProfileExpression drPepperProfile = StructureMapConfiguration.CreateProfile( "DrPepper" );
    drPepperProfile.For<ISoda>().UseConcreteType<DrPepper>();
    
    ProfileExpression dietCokeProfile = StructureMapConfiguration.CreateProfile("DietCoke");
    dietCokeProfile.For<ISoda>().UseConcreteType<DietCoke>();
    

    Setting the profiles

    ObjectFactory.Profile = "DrPepper";
    var consumer = ObjectFactory.GetInstance<Consumer>();
    
    // we now should have a consumer with an instance of DrPepper
    

    As you can see, setting up Contextual Binding in StructureMap is pretty easy and is a very powerful tool. 

    Till next time,

    [----- Remember to check out DimeCasts.Net -----]

  • If this is your manager, I feel bad for you

    While re-reading 'Implementing Lean Software Develpoment - From Concept to Cash' I came across a line that I had forgotten completly about, but rings so true (at least to me).

    The line is as follows:

    'A project manager who mostly updates Gantt charts and tells people what to do probably adds little value to the team'

    This line is in the context of what a 'leader' should be and a dictator is not of them.  If you have not read this book, I suggest you do.  It is a great read and just makes sense.

    Till next time,

  • [ANN] Reminder about Chicago Alt.Net

    This is just the friendly reminder to anyone that is out there about this months Chicago Alt.net meeting.

    Register at the usual location:
    http://altnetchicago.eventbrite.com/
    Continuous Integration with Cruise
    -------------------------------------------------
    6:00 pm
    Pizza and networking time


    6:30 pm
    Come see Robert Norton, tech lead of ThoughtWorks Cruise CI/Release


    Management product, talk about Cruise and how it helps managing
    software builds and deployments. ThoughtWorks is the force behind
    the Open Source CruiseControl.net and this new product is their
    commercial  offering in this segment.


    7:45 pm
    After the Cruise presentation, let's delve into more discussions about
    CI and configuration management. Bring your questions and experiences.
    * How complete should CI be?
    * How frequent?
    * How fast?
    * What tools are we using for CI?

    Till next time,

  • Setting an your RSS feed for ITunes

    If you would like to get your content (songs, screencasts or podcasts) into ITunes you will need to either modify or setup your RSS feed with the special 'iTunes' tags.  These tags are not part of the RSS standard (as far as I can see) but they will not hurt your RSS feed simply because they are there.

    I thought I would go through the steps needed to get your content into iTunes.

    Before we get started, you can get most of this information from this link, but you will have to wade through a bunch of noise.

    1. Modify your existing feed (example here)
      1. Need to modify the channel content
        You will need to add the following data to your channel content
        <itunes:subtitle> -- The info shown in the iTunes browser
        <itunes:author> -- Do I need to explain this
        <itunes:summary> -- Longer description about your product/site
        <itunes:owner>
          <itunes:name>/<itunes:email>
        <itunes:image> -- The cover art for you feed
        <itunes:category> -- Where does your feed go

      2. Need to modify the content of each item
        Fore each item in your feed you will also have to add a few extra tags
        <itunes:author> -- The author of that item
        <itunes:subtitle> -- The short desc for the item
        <itunes:summary> -- The long desc for the item
        <itunes:duration> -- How long is your podcast
        <itunes:keywords> -- How to find your podcasts
    2. Testing your feed in iTunes
      To test your feed you can simply register it directly in iTunes.  To do this you can do the following.
      Advanced Menu -> Subscribe to Podcast -> Provide the URL

    3. Submitting your feed to iTunes
      Submitting your feed is pretty easy, but it does take a day or so for it to be accepted in iTunes.  Click here to get details on how to submit your feed.
    4. Direct linking your feed to iTunes (opening up iTunes directly to your content)
      What is really cool is you can create a hyperlink on your site that will open up iTunes and take the person directly there.  All you need to do is add this URL
      http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=FEEDID
      Please note that FEEDID is unique to everyone and you will receive your ID in an email.

    There you go, 4 quick steps to get your feed up and running in iTunes.

    Till next time,

    [----- Remember to check out DimeCasts.Net -----]

  • Unused code is the worst of the 7 Wastes of Software

    Today I was having another round of conversations with a buddy of mine about the concept of waste and unused code.

    In agile there is a concept called YAGNI (You Ain't Gonna Need It) that basically states that you should not add code that is not immediately needed as it is waste.

    In Lean software this is known as one of the 7 Wastes of Software.  To quote from 'Implementing Lean Software Development'

    'The worst of the seven wastes of software development is adding features (read that as simply code) that are not needed to get the customers' current job done.'

    The context of our conversation was around code generation.  Now I am NOT a huge fan of CodeGen as I have been on the wrong side of a project that used CodeGen.  What we were debating was if it was just better to CodeGen up all the CRUD logic (they are using data driven design, not a domain driven approach) prior to needing it or create it as you need it.

    The conversation started with this statement from my buddy.

    'If I had to go stub a select out for a table, I'd be like WTF. Whoever created this app sucks, they did not even create select procs for me'

    When he made this statement I knew I was in for a uphill battle, but I tried to convey my thoughts.  However, at the end of the conversation we agreed to disagree (but he is still wrong :)) and we went back to our neutral corners.

    So, what are my thoughts on why unused code is waste:

    • You are creating speculative code for a need that you may or may not ever realize.  And my experience tells me more often then not that code will not be needed.
    • There is now more code to be maintained (in his case I have to modify/regen code if my db tables change) which leads to more work in the long run.
    • There is now more code to test, which means more tests to fix/refactor when that code changes.
    • There is now more code to refactor if you change directions later, and we all know you will change directions.
    • Your needs may/will change between the time you originally wrote the code and the time you needed it.

    The only real responses he could make were:

    • Since this code is created via CodeGen, who cares if it changes I can ReGen it.
      My response - This is a weak excuse as re-creating massive amounts of code is expensive and time consuming.  Also not mention everyone on the team may not necessarily know/understand how to do the CodeGen
    • I do not want to take time later to build the functionality out as I need it.  Especially when it comes to things like CRUD proc.
      My response - This is about the lamest excuse ever.  Creating the functionality as needed, when needed, is the ONLY want to correctly solve your business problem.

    So, what lesson have learned here today.  Unused code is waste and there is no 2 ways about it.

    Till next time,

    [----- Remember to check out DimeCasts.Net -----]

  • My wish list for the ASP.Net MVC Framework going forward.

    I have been using the MVC framework now for 3+ months.  In fact I already have a public production site running on the framework (www.dimecasts.net).  I have to say that I am really, really happy with the progress and direction that the team is making. 

    But I do have a few things I would like to throw out there as my 'Wish List'

    1. Do not seal any classes's.  There is no need to seal anything.  Once you seal stuff you are saying that no-one will EVERY want to make use of this class in a slightly different way.

      Examples: AuthorizeAttribute & HandleErrorAttribute.

      *** NOTE ***
      I have already been told per Scott Gu that this is going to happen in future releases, but just putting my wish out there.
      *** NOTE ***
    2. Try to make as much stuff as possible virtual (overrideable for you VB'ers out there).  This will allow us to extend our applications to better meet our needs.
    3. Make use of more Interfaces.  Since testing is really high on the list of priorities for the MVC using more interfaces for classes would simplify mocking and testing.

      Example: Anytime a ControllerContext is used (attributes) it is extremely painful to mock these things our for testing.
    4. Do not become afraid to implement breaking changes
    5. Keep up the good work.  I am really enjoying using this framework as I feel it makes my development experience much better.

    So there you go, my simple little wish list for the team.  I know it is nothing earth shattering, but I just wanted to get that out there.

    Till next time,

    [----- Remember to check out DimeCasts.Net -----]

  • Customer Service Fail - A eye opening experience

    Recently my wife, my son and I went into a local store (not going to mention which) to pickup an order that had been placed a few weeks back.  When we walked in we were asked to put our name on a 'waiting list' because they were so busy.  We went ahead and put our name on the list and were about 4th from being next. 

    After about a 15 minute wait, it was our turn to be helped and a friendly sales associate started to help us.  He asked us what we needed and I told him we were there to pickup an order that had arrived early that day.  He promptly went into the back to grab our merchandise and brought it out.  He then proceeded to finalized the order.  However at this point he abruptly stopped and excused himself to go speak with another employee.

    When he came back he simply told us that he could not finish processing our order, that another associate would have to do so.  But what sucked was that other associate was busy with another customer at the time so we had to wait... again.

    Fast forward 25 minutes (and 4-5 other people getting helped) and we had still not been helped.  At this point in time my wife asked our original sales associate why he could not help us (when he handed us off the first time he did not indicate why).  He then proceeded to tell us this

    The sales person that placed your order was not working today and only one person in the store was allowed to fulfil his orders.

    At this point my wife and I went nuts.  We asked that associate why this was.  He said 'we get paid on commission and the original associate needed to get credit for the sale'.

    So we proceeded to wait another 10 minutes until the ONLY sales associate that could help us finished up with his customers.

    So, you may be asking yourself, where is the fail in this scenario.... Oh let me tell you.

    What kind of company setups their system so that customer MUST wait 1 hour to pickup an order that has already been paid for simply because the associate that placed the order was not working that day.

    Needless to say we will NOT be returning back to that store ever again (unless it is absolutely necessary) and we have already logged an official complaint with the company.

    Till next time,

    [----- Remember to check out DimeCasts.Net -----]

  • Managing SVN via SlickEdit

    Anyone that has used Svn (Subversion) for any length of time knows that it is a kick-ass source control system.  But what does drive some people away is the fact that to manage your files you either need to use the command line or download the TortoiseSVN client.

    Now using the TortoiseSVN Client is a snap and to be honest is a great way to get started, but not having a SVN client that integrates into Visual Studio is a turn off to many people.  Well the good news is that SlickEdit tools has a nice plug-in that will allow you to connect to an mange your SVN repository. 

    Setting up your IDE to use the plug-in is easy as pie, and I will show you below.

    1. Navigate to Tools -> Options -> SlickEdit -> Versioning Toolbox -> Source Control Providers.  Once there provide the path to your SVN.exe and set the active provider.
      SetupSVNProvider 
    2. Navigate to Tools -> Options -> Source Control -> Plug-in Selection and set the current provider to be the SlickEdit CVS/SVN plug-in.
      SetupVSProvider
    3. Now you can use right click any file in your Solution Explorer and get the following menu.
      SolutionExplorerMenu

    Hope this helps and check out the other great tools that SlickEdit has for reviewing and maintaining your source control system.

    Till next time,

    [----- Remember to check out DimeCasts.Net -----]

  • Wow, there went 120gig a transfer

    So, it is official DimeCasts.Net needs to start offloading bandwidth over to Amazon's S3 service.  I held out as long as I could, but last month I almost topped my 'free' bandwidth allocation and S3 is 5times cheaper then my host.

    I knew this day would come, and I have to say it is kinda a bitter sweet moment.  On one hand monthly costs just went up (hey, anyone out there want to sponsor an episode????) but it also means that the sites traffic has ben going up.

    I would like to give a special shout-to the various guest authors for helping me make this a great success.

    In Order of Appearance

    Thanks for all the support,

    Till next time,

More Posts

Our Sponsors

Proudly Partnered With


This Blog

Syndication

News