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

Eric Wise

Business & .NET

October 2005 - Posts

  • Antec NEOPOWER 480 watt

    Yeah, not a programming topic but I just wanted to say that I am damn impressed with the quality of this power supply.  I picked it up this weekend to power my new Athlon 3800+ dual core and GeForce 7800 GT video card and this power supply is by far the most quiet one I've ever encountered.  The loudest thing in my case now is my hard drives!

    It's also the first power supply I've ever had that has the cables organized as pluggable components.  Basically on the back of the supply in the case there are ports to plug the cables into, so you only plug in as many as you use which is fantastic compared to my old one which basically required me to cram all the uneeded cables into the slot where the floppy would go (if I had one).

    Anyways, if you're a build your own pc type person like me, this is the one to get, it was ~$120.

  • Rural-Sourcing

    Sahil doesn't care for telecommuting.  I, however, am a big fan of it under the right conditions.  The right conditions being a project guideline and scope that allows developers to do the majority of their work with a minimum of interaction.  Good examples of this are modular development (modules being fairly independent of eachother),or situations where an API/business layer is already implemented and they are simply building on top of it.  (Here's the api, build me a UI)

    The main downside of the telecommuter is that you don't get the human interaction that some projects require.  An interesting paradigm has been making its way through some business circles though, the concept of rural-sourcing.  In rural sourcing you outsource your development to developers in low cost areas.  Take a typical senior developer in New York City versus the same developer in Omaha, Nebraska (beautiful city btw).  For a basis of comparison we'll use salary.com programmer IV.

    You'll find that in Omaha this position is worth a median of $80,722.  In New York City this position has a median of $98,073.  So you have about a $17,500 difference in just salary.  Now toss in the higher taxes you pay in New York versus Nebraska, in addition to the various overhead of having a worker in an office (office space, office supplies, parking (particularily in NYC).  You quickly begin to realize that you can save a pretty significant sum by moving the job off-site.

    Some people have a problem with the whole "not being in the office" concept of a telecommuting worker.  So let's head over to expedia and see what the cost of a flight from omaha to NYC is.  For 4 days.  You'll find the answer is around $300 (of course you could probably get a better rate if you did it frequently via negotiation, corp discount).  So now we potentially have a situation where you bring your telecommuters in for that special face time once a month.  Figure in an average hotel with internet, and a decent meal allowance... I'll pull a number out of my head, we'll say $600 considering a $100/night room and $50 per day for food.  So it'll run you about $9,800 to bring a telecommuter in one week a month for a year.  At this point we've saved at least $7,700 per worker in just salary.  When you figure in the lower overhead costs it's even better.

    Other potential savings?

    • Most telecommuters will supply their own computer.  Chunk off another $1,000 - $2,000.  Plus realize that the kind of machine someone buys on their own is usually of much better quality than the ones most companies "assign".
    • The median salary in salary.com is for an office worker.  The majority of people I know would take a paycut if they were allowed to work from home on a regular basis.  I know I would.
    • Many people leave their work in the office.  If your work is in your home, you can have an epiphany after hours and sign in to be productive.

    Now, this is all assuming you have telecommuters scattered to the four winds.  The true concept of rural sourcing is setting up shop somewhere nice and inexpensive, generally in the midwest.  You import developers to that area so they can meet to discuss things and then the flying concept only applies to the select few team leads who need to do so.  That's where the big savings come in.  I've encountered several companies that have their media and marketing arms in the big city where the action is and their IT arms are in low cost areas.  Usually it is a win/win scenario as well because that salary goes a lot farther in Omaha than it does in NYC.

    The question in the end is: Would you rather hire 15 expensive programmers in NYC who may or may not be the most skilled available or hire15 lower cost workers from anywhere in the country where the pool of candidates is huge and you can demand a higher quality than you can locally where your candidate pool is limited?

  • Using Telerik's RadMenu to handle Roles

    My company has been a customer of Telerik for about 6 months now, and we've been nothing but happy with the service and support we've gotten from them and the continuous improvement of quality in their controls.  I highly recommend checking them out.

    Anyways, recently I was asked whether I could implement some role based security for displaying the items of a telerik menu so here is how I wired it up programatically.

    Step 1: Create XML File

    The first step was to create an xml file with the format and fields I needed for the menu items.  Instead of using the group xml codes like in the telerik samples, I settled for a parent/child id relationship.  So the end result is xml items with itemId, parentId (if null it's a top level item), navigateurl, text, target, and roles.  Note that the item and parent id's aren't numbers, they must be strings.  Like so:

    <MainMenu>

    <Item>

    <menuItemID>i1</menuItemID>

    <menuText>Distribute Inventory</menuText>

    </Item>

    <Item>

    <menuItemID>i2</menuItemID>

    <parentItem>i1</parentItem>

    <menuText>Overall</menuText>

    <navigateURL></navigateURL>

    <target></target>

    <roles></roles>

    </Item>

    <Item>

    <menuItemID>i3</menuItemID>

    <parentItem>i1</parentItem>

    <menuText>By Individual</menuText>

    <navigateURL></navigateURL>

    <target></target>

    <roles></roles>

    </Item>

    // etc

    </MainMenu>

     

    Step 2: Load and Cache the dataset/handle roles.

    Since the menu structure will be accessed fairly frequently, it makes sense to cache it.  Also, we need a function to check the roles since if the role tag is blank we need to handle that as "public".  Note that you could delimit multiple roles into this tag but that is beyond the scope of this sample.  For simplicity, we will use the dataset's ReadXML method.  Notice that we are setting up a relation to link up the parent/child ids.

        Private Function CheckRole(ByVal roles As String)

            If roles = "" Then Return True

            Return context.User.IsInRole(roles)

        End Function

     

        Private Function GetMenuItems() As DataSet

            Dim ds As DataSet

     

            If Not IsNothing(Cache("MenuItems")) Then

                ds = CType(Cache.Get("MenuItems"), DataSet)

            Else

                ds = New DataSet

                ds.ReadXml(MapPath("~\XML\MainMenu.xml"))

                ds.Relations.Add("ItemRelation", ds.Tables(0).Columns("menuItemID"), ds.Tables(0).Columns("parentItem"))

                Cache.Add("MenuItems", ds, Nothing, DateTime.Now.AddHours(4), Nothing, Caching.CacheItemPriority.AboveNormal, Nothing)

            End If

     

            Return ds

        End Function

     

    Step 3: Create a method for building a menu item from a datarow

    Since we'll be walking the dataset and grabbing menu item information from datarows, we need a method to handle parsing the data.  Simple enough:

        Private Sub CreateItem(ByRef item As MenuItem, ByRef dbRow As DataRow)

            item.Text = Convert.ToString(dbRow("menuText"))

            item.ID = Convert.ToString(dbRow("MenuItemID"))

     

            If Not IsDBNull(dbRow("navigateURL")) Then

                item.Href = Convert.ToString(dbRow("navigateURL"))

            End If

     

            If Not IsDBNull(dbRow("target")) Then

                item.Target = Convert.ToString(dbRow("target"))

            End If

        End Sub

     

    Step 4: Loop all the top level items

    Remember I said the top level items are items where the parentid is null.  We need to loop the dataset and find all the parent items, when a parent item is found we need to load its child items.

        Protected Sub GenerateMainMenu()

            Dim addItem As Boolean

            Dim ds As DataSet = GetMenuItems()

     

            'Setup Menu

            Dim topGroup As New MenuGroup(RadMenu1)

            topGroup.Flow = PresentationDirection.Horizontal

            topGroup.ExpandDirection = ExpandDirection.Down

            RadMenu1.RootGroup = topGroup

     

            For Each dbRow As DataRow In ds.Tables(0).Rows

                addItem = False

                'Top level rows have a null parentItem

                'We will catch all the top items then query their children to build the menu

                If dbRow.IsNull("parentItem") Then

                    If Not IsDBNull(dbRow("roles")) Then

                        addItem = CheckRole(dbRow("roles"))

                    Else

                        addItem = True

                    End If

                End If

     

                If addItem Then

                    Dim item As New MenuItem(topGroup)

                    CreateItem(item, dbRow)

                    RecursivelyPopulate(dbRow, item)

                    topGroup.AddItem(item)

                End If

            Next dbRow

        End Sub

     

    Step 5: Recursively Populate the Child Items

    The final step is to write the RecursivelyPopulate method which will take a parent item and query the dataset to see if there are child rows, if there are it will wire them up and then pass them through the same function (so it will go down multiple levels indefinitely).  Here's the code:

        Private Sub RecursivelyPopulate(ByRef parentRow As DataRow, ByRef parentItem As MenuItem)

            Dim childRow As DataRow

            Dim addItem As Boolean

            Dim childGroup As MenuGroup

     

            For Each childRow In parentRow.GetChildRows("ItemRelation")

                addItem = False

     

                'instantiate group if necessary, we're doing it in the loop since we only want the group if there are child items

                If IsNothing(childGroup) Then

                    childGroup = New MenuGroup(parentItem)

                    childGroup = parentItem.AddChildGroup()

                    childGroup.Flow = PresentationDirection.Vertical

                End If

     

                If Not IsDBNull(childRow("roles")) Then

                    addItem = CheckRole(childRow("roles"))

                Else

                    addItem = True

                End If

     

                If addItem Then

                    Dim item As New MenuItem(childGroup)

                    CreateItem(item, childRow)

                    RecursivelyPopulate(childRow, item)

                    childGroup.AddItem(item)

                End If

            Next childRow

        End Sub

     

    So you can see, Telerik's menu control is very flexible and even if you want to do some things outside the scope of their standard examples you can do so without much hassle!

  • A quick good luck

    I want to wish a quick goodluck to my friend Raza on his new Easy Attention product release.  In brief, the product allows you to generate website notifications with a collection of nice little templates.  You can embed links and formated text into the templates and they pop over the website content in a hover style.

    I happen to not be a member of the pop-ups are evil crowd.  Like most things in this world, it's not the tool that is evil, but the use that people put it towards.  Raza's product is a quick and easy way to generate nicely formatted notifications via javascript.  I could definitely see using something like this to inform customers of system downtime, upcoming events, etc.

    Anyways, he does have a free trial download, so check it out here.  I'm pleased to see a fellow ISV owner launch their product.  Hopefully he makes more money than easy assets .net... which has many downloads and several production users but not much in the way of donations.

  • Business Blog

    http://sixdisciplines.blogspot.com/

    I stumbled across this when I was taking some "me" time this weekend and just cruising the net.  There are some interesting articles in there.  Apparently this company is moving into my area (Cleveland).  Maybe I'll bump into some of their consultants at a local event.  They have an interesting website.

  • Easy Assets - Create User Error

    To fix the Object Reference Error simply open the Webmodules/Admin/EditUser.aspx.vb file.  Then in the btnSave_Click method change all the variables of thisUser to editUser.

    Recompile and it should work properly!  I'll post a new zip file sometime this week.

    Sorry it took so long to get an answer back, I've been hella busy lately with building my new house.

     

    One interesting note is that I had uninstalled sql server 2000 to play with the sql server 2005 CTP so I either had to install it again or try to run the db installer against 2005.  I ran the db installer against the 2005 CTP and it worked fine!  You just have to be sure to set the EasyUser accounts password to a strong password after the installer runs if you have that server option on and update the dataconfiguration.config file.  Enterprise Library had no issues running against the CTP as far as I could tell in my limited time.  This should take some of the burden off converting this bad boy to .net 2.0/sql 2005.

More Posts