tag:blogger.com,1999:blog-1343524703759076442024-03-12T20:57:44.707-07:00Ahmad's BlogAdnan Ahmadhttp://www.blogger.com/profile/01008287176974220401noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-134352470375907644.post-18945134698243780382013-05-06T06:15:00.002-07:002020-03-25T11:10:22.018-07:00Automation in Agile <span style="font-family: "arial" , sans-serif; font-size: 12pt; line-height: 200%;"><br /></span>
<span style="font-family: "arial" , sans-serif; font-size: 12pt; line-height: 200%;">If there is anything that I have learned in my software
development career it is that all development is Agile whether you call it that
or not. Agile is fast, lean, dynamic and unforgiving. The development team is
in a constant tug of war with requirements and at the same time trying to
maintain quality. This poses a great challenge which Agile teams must learn to
overcome. How do we balance quality with new functionality? The simple answer
is automation. Automation is key for any successful Agile team.</span><br />
<br />
<div class="MsoNormal" style="line-height: 200%; margin: 0in 0in 10pt;">
<span style="font-family: "arial" , "sans-serif"; font-size: 12pt; line-height: 200%;">Automation is simply the process of automating tasks within
your software development and testing process. In a true Agile environment,
software development is performed at such a fast pace that if there is anything
that can be automated, it must be automated. We need to free up the development
team from repetitive tasks to focus on building new things and fixing bugs. There
is hardly any time to waste. One area where automation has existed for some time
now, is the build process. If anyone has ever written a build script that
compiles the application and puts out a released version of the software, then
you have done automation. Every time the build fires whether using any build
technology such as CruiseControl, Nant, or MSBuild, the build is automatically
kicked off compiled, packaged and deployed to a server as a release
for testers or anyone else to pick up. This is essential for virtually any
software team out there, regardless of size. Automating the build eliminates
one of the basic tasks that have to be done regularly and possibly multiple
times a day. This keeps the team free from having any valuable resource tied up
so that the team can focus on the more important aspects of software
development.<o:p></o:p></span></div>
<br />
<div class="MsoNormal" style="line-height: 200%; margin: 0in 0in 10pt;">
<span style="font-family: "arial" , "sans-serif"; font-size: 12pt; line-height: 200%;">Now we come to a slightly more advanced form of
automation called Automated Testing. Once a build is created successfully, to
assure it’s a quality build, a set of basic tests must be performed on it. This
can be called a build verification test or a smoke test. The basic idea is to
make sure that the piece of software that was just created is any good. Does it
install? Does it even launch? Can it be deployed on a server? Whatever your software
may do, there will be a set of very basic features that it must be able to do
say it works, even if it may have bugs further down. This is something a lot of
QA teams do as part of their daily routine. Their job is to verify and give a
green light that the build has passed the basic tests and can be tested further
for more regression, adhoc or exploratory testing. The challenge is that if
your team wants to be Agile, this process should also be automated. A set of
automation scripts or tests need to be built that perform this task unattended
or automatically as frequently as possible; if not after every build then at least
once a day. As the team is focusing on building new features or completing user
stories, the automation is providing the necessary confidence and support to
make sure that no major functionality is getting broken and the software still
can be considered stable to be potentially shippable. This also reduces any unforeseen
major bugs to creep in and surface when it comes time to close out a sprint or an
iteration. Giving the team and its stake holders, greater confidence in the
software they are producing.<o:p></o:p></span></div>
<br />
<div class="MsoNormal" style="line-height: 200%; margin: 0in 0in 10pt;">
<span style="font-family: "arial" , "sans-serif"; font-size: 12pt; line-height: 200%;">While automation can be applied to many aspects of the
development process, these two areas of automation are absolutely essential.
Getting an automated build and automated test will give the team a strong
foundation to build upon and increase development quality and speed. Remember,
automation saves time and time is money!<o:p></o:p></span></div>
Adnan Ahmadhttp://www.blogger.com/profile/01008287176974220401noreply@blogger.com214tag:blogger.com,1999:blog-134352470375907644.post-46235401662270380942012-12-10T09:20:00.000-08:002012-12-10T09:24:51.741-08:00The Tale of a ConsultantAs a consultant I am constantly being interviewed and am always asked the question, "Tell me a little about yourself and your background." No offense to the questioner but it is painful for me to repeat myself constantly. But it is his right to know who I am versus the other guy he spoke to so here I will describe myself briefly for the benefit of everyone.<br />
<br />
I am programmer by hobby and profession. I have been coding since as long as I can remember. I remember bragging about my little cursor driven drawing program in 6th grade written in GWBasic. I went on to complete school and college with a Bachelor's degree in Computer Science and then a Master's in Computer Information Systems.<br />
<br />
During my undergraduate studies I worked as an intern in a small startup called Quantum Software developing VB 6 code and small apps. There I began to understand the software lifecycle; requirements gathering, development, testing, deploying, etc. The whole nine yards. It was truly a learning experience and being in a startup it was a fast paced challenging environment.<br />
<br />
After that, while I was in graduate school I was hired as a Lab Administrator. There my constant fiddling around with new technologies impressed my professor and we started playing around and writing papers together on some of the new stuff that was coming out in the early 2000s like XML, .NET, Web Services, Web Development Linux, etc. While I was doing that, I had gained enough Web Development skills that I started getting consulting projects to do different websites. That was the beginning of my consulting career.<br />
<br />
Soon after I graduated I started consulting fulltime with different consulting companies. Working with numerous clients in various industries ranging from health care to energy and financial I was addicted to fast paced challenging work. My drive to always find a better way to do something, and trying to improve the code quality of a project often got me praises but sometimes lead to trouble. Being the one who cries fox does not always get you in good standing with your manager. Nevertheless, I never compromised on my basic principles of software development such as designing your code before writing it, finding ways of improving badly written code, and using proven industry standards, patterns and practices for common problems, etc.<br />
<br />
My biggest example of that was at a large scale enterprise project project in one of the biggest energy companies in the world. I was a back-end developer writing service layer code and interacting heavily with NHibernate and the Database. Well into the project, major performance and development issues started appearing in the application. I began to see that my NHibernate calls and queries were getting harder to write and the data coming back was inconsistent and slower than what was expected. It was clear that working with a legacy database where the data requirements were constantly changing NHibernate was a poor choice for the data layer. I have written extensively in blogs and forums as to the problems I faced. I will summarize and say that the developers and BAs were extremely joyful when I wrote some code that directly utilized SQL queries and was able to populate the screens through the service layer. Furthermore, we had developed a little tool that would automate this process of building complex SQL queries and visually mapping them to regular business objects. The tool then generated all the painful ADO.NET code that no one wanted to write or see.<br />
<br />
This caused a stir in the project management and architecture teams. Some were excited while others saw a potential threat. To say the least, me and my partner who helped me showcase the tool were relieved of our duties and went on to found our own start-up to build custom mapping and code generation tool.<br />
<br />
Since then I have been in and out of consulting roles in Houston's leading energy and financial firms.<br />
<br />
Throughout my career my focus has been on Architecture and good design with focus on code quality. I like to architect my projects and implement the code necessary to prove the architecture is working to solve the business need. I don't beleive in "plug and play" architecture where a number of open source or existing frameworks are mashed up to create an architecture that has all the latest technologies but does not meet the business challenges on hand. I also am not a fan of the "whiteboard" architects who always stay at a high level and are abstract about their designs leaving all the details to developers. They are unable to grasp the challenges a developer faces in solving the business problems and dont provide effective architectural solutions. I understand that communication is at the heart of a successful project. I have learnt that managing developers is a very tricky job where there is always a constant influx of ideas and creativity that is required to be harnessed and channelled into succesfully completing a project. Not appreciating a developer's creativity can lead to serious consequences. Creating processess and infrastructure to allow developers to produce their best work requires a great deal of effort. It requires establishing well defined and stable processes for source control, change management, testing, building, and deployment. Being hands on and being a leader by being an example for the rest of the team is the only form of leadership I believe in.<br />
<br />
To conclude, I am an easy going guy, who is always very easy to talk to and loves technology. Software development and consulting is and has always been my passion.Adnan Ahmadhttp://www.blogger.com/profile/01008287176974220401noreply@blogger.com3tag:blogger.com,1999:blog-134352470375907644.post-70144211608828766422011-02-26T12:50:00.001-08:002011-02-26T13:04:17.377-08:00Portfolio<a href="http://2.bp.blogspot.com/-HgLOsLRTmS0/TWlqbvGwelI/AAAAAAAAAZw/DemYXbiZ5Rw/s1600/Portfolio.png"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/-HgLOsLRTmS0/TWlqbvGwelI/AAAAAAAAAZw/DemYXbiZ5Rw/s1600/Portfolio.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5578106638208891474" /></a>Adnan Ahmadhttp://www.blogger.com/profile/01008287176974220401noreply@blogger.comtag:blogger.com,1999:blog-134352470375907644.post-66896477474309404582009-07-04T16:23:00.001-07:002009-07-04T16:25:58.119-07:00Simple Tag Cloud Implementation for ASP.NET MVC<p> </p> <p>I read this <a href="http://www.mikesdotnetting.com/Article.aspx?ArticleID=107">post</a> by Mikesdotnetting a few days ago when I was trying to implement a Tag Cloud for our open source forum project <a href="http://www.subforum.net">SubForum</a>. Although it was a good post and got me started on how to do it, I found it a bit complex for what I needed. One of the complications that I saw was obviously the Entity Framework and the data layer that Mike talked about to build the Tag Cloud. The data I needed was quite simple and didn’t need to be that complex.</p> <p>I decided to implement a simple ASP.NET MVC Tag Cloud using plain SQL and a simple table structure. Also, I did not want categories. I just wanted posts and post tags, so that my Tag Cloud could more accurately represent the Tags in the posts.</p> <p><strong>RenderAction Approach</strong></p> <p>I decided to use the RenderAction approach introduced in the <a href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471#DownloadId=61773">MVC Futures</a> library. This helped me strongly type the Tag Cloud partial view to a Model and a specific action in the Controller that populates the model. This is helpful because the Model for the main page is different from the Model for the TagCloud and I wanted to avoid adding the Tag Cloud model to the ViewData collection as a dictionary value. You can read Jimmy Bogard’s <a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/18/the-filter-viewdata-anti-pattern.aspx">post</a> for more about the benefits of RenderAction.</p> <p><strong>The Steps</strong></p> <p>Back to the Tag Cloud. Let me start with the Database model:</p> <p><a href="http://lh4.ggpht.com/_N5aAiuG68RA/Sk_kVMswLKI/AAAAAAAAAYQ/aaYZP-Zuv2Y/s1600-h/image11.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="211" alt="image" src="http://lh5.ggpht.com/_N5aAiuG68RA/Sk_kVYF4tiI/AAAAAAAAAYU/ItvKojo0nKw/image_thumb7.png?imgmax=800" width="494" border="0" /></a></p> <p> </p> <p>The Post and Tag object are used to represent a Post and a List of Tags:</p> <pre class="csharpcode"> <a href="http://lh6.ggpht.com/_N5aAiuG68RA/Sk_kVw4HWRI/AAAAAAAAAYY/cpWtEkop4dM/s1600-h/image16.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="420" alt="image" src="http://lh6.ggpht.com/_N5aAiuG68RA/Sk_kWPhGMLI/AAAAAAAAAYc/KyPhLCLoYlE/image_thumb10.png?imgmax=800" width="408" border="0" /></a> </pre><br /><br /><p>The way it works is that every time a post is added, the comma separated tags associated with it are taken and inserted as individual tags in the PostTags table.</p><br /><br /><p>We need to pull all the information from the database to perform our Tag Cloud calculations. We need the number of times each tag occurs in the system, the Tag itself and the total number of posts in the system. We can pull all this information in one simple query:</p><br /><br /><blockquote><br /> <pre><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Select&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Select</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Count&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Count</a>(1) <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=As&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">As</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Count&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Count</a>, PostTags.Tag <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=As&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">As</a> Tag, (<a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Select&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Select</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Count&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Count</a>(*)<br /> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=From&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">From</a> Posts) <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=As&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">As</a> TotalPosts<br /> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=From&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">From</a> PostTags<br /><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Group&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Group</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=By&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">By</a> PostTags.Tag<br /><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Order&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Order</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=By&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">By</a> '<span style="color: #8b0000">Count</span>' <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Desc&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Desc</a></pre><br /></blockquote><br /><br /><p><!-- .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } --></p><br /><br /><p>The result of executing this query against our test database returns:</p><br /><br /><p><a href="http://lh6.ggpht.com/_N5aAiuG68RA/Sk_kWfxBCdI/AAAAAAAAAYg/ziFyAJz4WAY/s1600-h/image21.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="206" alt="image" src="http://lh5.ggpht.com/_N5aAiuG68RA/Sk_kW7wuEBI/AAAAAAAAAYk/iWyBB-T1UFk/image_thumb13.png?imgmax=800" width="515" border="0" /></a></p><br /><br /><p>As you can see, this shows the tag, the number of times it occurs in the system and the total number of posts in the system. We can then return this data through the TagCount object (which has just three properties: Count, Tag and TotalPosts) from our Data Layer function GetTagCloud: </p><br /><br /><p></p><br /><br /><div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6898a19b-1712-4db6-ae10-5e0b13eb47ce" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px; padding-top: 5px"><br /><div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"><br /><div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap"><br /><p><br /><br /> <span style="color:#0000ff">public</span> <span style="color:#2b91af">IList</span><SubForum.DataAccess.Objects.<span style="color:#2b91af">TagCount</span>> GetTagCloud()<br><br /> {<br><br /> System.Data.<span style="color:#2b91af">IDbCommand</span> command = <span style="color:#0000ff">null</span>;<br><br /> <span style="color:#2b91af">IDataReader</span> dataReader = <span style="color:#0000ff">null</span>;<br><br /> <span style="color:#2b91af">List</span><SubForum.DataAccess.Objects.<span style="color:#2b91af">TagCount</span>> returnList = <span style="color:#0000ff">new</span> <span style="color:#2b91af">List</span><SubForum.DataAccess.Objects.<span style="color:#2b91af">TagCount</span>>();<br><br /> <span style="color:#2b91af">IDbConnection</span> connection = <span style="color:#0000ff">new</span> System.Data.SqlClient.<span style="color:#2b91af">SqlConnection</span>(<span style="color:#0000ff">this</span>.ConnectionString);<br><br /> <span style="color:#0000ff">try</span><br><br /> {<br><br /> connection.Open();<br><br /> command = connection.CreateCommand();<br><br /> command.CommandText = <span style="color:#a31515">"Select Count(1) As Count, PostTags.Tag As Tag, (select count(*) from Posts) as To"</span> +<br><br /> <span style="color:#a31515">"talPosts\nFrom PostTags\nGroup By PostTags.Tag\nOrder By \'Count\' Desc"</span>;<br><br /> System.<span style="color:#2b91af">Console</span>.WriteLine(<span style="color:#a31515">"Executing Query: {0}"</span>, command.CommandText);<br><br /> dataReader = command.ExecuteReader();<br><br /> <span style="color:#0000ff">for</span> (<br><br /> ; dataReader.Read(); <br><br /> )<br><br /> {<br><br /><br><br /> SubForum.DataAccess.Objects.<span style="color:#2b91af">TagCount</span> modelObj = <span style="color:#0000ff">new</span> SubForum.DataAccess.Objects.<span style="color:#2b91af">TagCount</span>();<br><br /> modelObj.Tag = ((<span style="color:#2b91af">String</span>)(dataReader[<span style="color:#a31515">"Tag"</span>]));<br><br /> <span style="color:#0000ff">if</span> ((dataReader[<span style="color:#a31515">"Count"</span>].Equals(<span style="color:#2b91af">DBNull</span>.Value) == <span style="color:#0000ff">false</span>))<br><br /> {<br><br /> modelObj.Count = ((<span style="color:#0000ff">int</span>)(dataReader[<span style="color:#a31515">"Count"</span>]));<br><br /> }<br><br /> <span style="color:#0000ff">else</span><br><br /> {<br><br /> modelObj.Count = <span style="color:#0000ff">null</span>;<br><br /> }<br><br /> <span style="color:#0000ff">if</span> ((dataReader[<span style="color:#a31515">"TotalPosts"</span>].Equals(<span style="color:#2b91af">DBNull</span>.Value) == <span style="color:#0000ff">false</span>))<br><br /> {<br><br /> modelObj.TotalPosts = ((<span style="color:#0000ff">int</span>)(dataReader[<span style="color:#a31515">"TotalPosts"</span>]));<br><br /> }<br><br /> <span style="color:#0000ff">else</span><br><br /> {<br><br /> modelObj.TotalPosts = <span style="color:#0000ff">null</span>;<br><br /> }<br><br /> returnList.Add(modelObj);<br><br /> }<br><br /> }<br><br /> <span style="color:#0000ff">finally</span><br><br /> {<br><br /> <span style="color:#0000ff">if</span> ((dataReader != <span style="color:#0000ff">null</span>))<br><br /> {<br><br /> ((System.<span style="color:#2b91af">IDisposable</span>)(dataReader)).Dispose();<br><br /> }<br><br /> <span style="color:#0000ff">if</span> ((command != <span style="color:#0000ff">null</span>))<br><br /> {<br><br /> ((System.<span style="color:#2b91af">IDisposable</span>)(command)).Dispose();<br><br /> }<br><br /> <span style="color:#0000ff">if</span> ((connection != <span style="color:#0000ff">null</span>))<br><br /> {<br><br /> connection.Close();<br><br /> ((System.<span style="color:#2b91af">IDisposable</span>)(connection)).Dispose();<br><br /> }<br><br /> }<br><br /> <span style="color:#0000ff">return</span> returnList;<br><br /> \<br /></p><br /></div><br /></div><br /></div><br /><br /><p>  The ForumController that handles all the Forum MVC requests has a GetTagCloud() function that returns the model for the View:</p><br /><br /><div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:42023000-a0d8-44c0-b1cc-193c28f7fc6f" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px; padding-top: 5px"><br /><div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"><br /><div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap"><br /><p><br /><br /> <span style="color:#0000ff">public</span> <span style="color:#2b91af">ActionResult</span> TagCloud()<br><br /> {<br><br /><br><br /> <span style="color:#2b91af">IList</span><<span style="color:#2b91af">TagCount</span>> tagCountList = DataAccessService.GetTagCloud();<br><br /> <br><br /> <span style="color:#0000ff">return</span> View(tagCountList);<br><br /> \<br /></p><br /></div><br /></div><br /></div><br /><br /><p>Then comes the user control or the MVC Partial View that displays the tags as links with the right Tag class to use. TagCloud.ascx: </p><br /><br /><div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2087668f-4336-4b97-a772-b0595bd29048" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px; padding-top: 5px"><br /><div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"><br /><div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap"><br /><p><br /><br /><span style="background:#ffee62"><%</span><span style="color:#0000ff">@</span> <span style="color:#a31515">Control</span> <span style="color:#ff0000">Language</span><span style="color:#0000ff">="C#"</span> <span style="color:#ff0000">Inherits</span><span style="color:#0000ff">="System.Web.Mvc.ViewUserControl<IList<SubForum.DataAccess.Objects.TagCount>>"</span> <span style="background:#ffee62">%><br><br /></span><span style="color:#0000ff"><</span><span style="color:#a31515">h5</span><span style="color:#0000ff">></span>Tags<span style="color:#0000ff"></</span><span style="color:#a31515">h5</span><span style="color:#0000ff">><br><br /><</span><span style="color:#a31515">ul</span><span style="color:#0000ff">><br><br /></span><span style="background:#ffee62"><%</span><span> <br><br /></span><span style="color:#0000ff">int</span> totalNumberOfTags = <span style="color:#0000ff">base</span>.Model.Count;<br><br /><br><br /><span style="color:#0000ff">foreach</span> (SubForum.DataAccess.Objects.<span style="color:#2b91af">TagCount</span> tagCount <span style="color:#0000ff">in</span> <span style="color:#0000ff">base</span>.Model)<br><br />{<br><br /> <span style="color:#0000ff">if</span> (!<span style="color:#0000ff">string</span>.IsNullOrEmpty(tagCount.Tag))<br><br /> {<br><br /> <span style="color:#0000ff">string</span> tagClass = SubForum.Web.Controllers.<span style="color:#2b91af">ForumController</span>.GetTagClass(tagCount.Count.Value, tagCount.TotalPosts.Value);<br><br /><span style="background:#ffee62">%></span><span> </span><span style="color:#0000ff"><</span><span style="color:#a31515">li</span><span style="color:#0000ff">></span><span style="background:#ffee62"><%</span><span style="color:#0000ff">=</span>Html.RouteLink(<br><br /> tagCount.Tag,<br><br /> <span style="color:#a31515">"Tag"</span>,<br><br /> <span style="color:#0000ff">new</span><br><br /> {<br><br /> controller = <span style="color:#a31515">"Forum"</span>,<br><br /> action = <span style="color:#a31515">"Tag"</span>,<br><br /> id = tagCount.Tag<br><br /> },<br><br /> <span style="color:#0000ff">new</span> { id = tagClass }<br><br /> )<span style="background:#ffee62">%></span><span style="color:#0000ff"></</span><span style="color:#a31515">li</span><span style="color:#0000ff">></span><br><br /> <span style="background:#ffee62"><%</span><span>}<br><br />}</span><span style="background:#ffee62">%></span><span style="color:#0000ff"></</span><span style="color:#a31515">ul</span><span style="color:#0000ff">><br><br /></span><br /></p><br /></div><br /></div><br /></div><br /><br /><p>The UI calls the GetTagClass() function to determine which TagClass from the CSS to use:</p><br /><br /><div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1fd5a669-cc73-4bbc-aa85-850d284b3ef3" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px; padding-top: 5px"><br /><div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"><br /><div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap"><br /><p><br /><br /> <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">string</span> GetTagClass(<span style="color:#0000ff">int</span> category, <span style="color:#0000ff">int</span> articles)<br><br /> {<br><br /> <span style="color:#0000ff">var</span> result = (category * 100) / articles;<br><br /> <span style="color:#0000ff">if</span> (result <= 1)<br><br /> <span style="color:#0000ff">return</span> <span style="color:#a31515">"tag1"</span>;<br><br /> <span style="color:#0000ff">if</span> (result <= 4)<br><br /> <span style="color:#0000ff">return</span> <span style="color:#a31515">"tag2"</span>;<br><br /> <span style="color:#0000ff">if</span> (result <= 8)<br><br /> <span style="color:#0000ff">return</span> <span style="color:#a31515">"tag3"</span>;<br><br /> <span style="color:#0000ff">if</span> (result <= 12)<br><br /> <span style="color:#0000ff">return</span> <span style="color:#a31515">"tag4"</span>;<br><br /> <span style="color:#0000ff">if</span> (result <= 18)<br><br /> <span style="color:#0000ff">return</span> <span style="color:#a31515">"tag5"</span>;<br><br /> <span style="color:#0000ff">if</span> (result <= 30)<br><br /> <span style="color:#0000ff">return</span> <span style="color:#a31515">"tag5"</span>;<br><br /> <span style="color:#0000ff">return</span> result <= 50 ? <span style="color:#a31515">"tag6"</span> : <span style="color:#a31515">""</span>;<br><br /> }<br><br /><br /></p><br /></div><br /></div><br /></div><br /><br /><p>These Tag classes match our CSS that has the following definition: </p><br /><br /><div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:abd0d998-d360-4611-863c-3b65c6387d64" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px; padding-top: 5px"><br /><div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"><br /><div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap"><br /><p><br /><br /><br><br /> <span style="color:#a31515">.tag1</span>{<span style="color:#ff0000">font-size</span>: <span style="color:#0000ff">0.8</span> <span style="color:#0000ff">em</span>}<br><br /><span style="color:#a31515">.tag2</span>{<span style="color:#ff0000">font-size</span>: <span style="color:#0000ff">0.9em</span>}<br><br /><span style="color:#a31515">.tag3</span>{<span style="color:#ff0000">font-size</span>: <span style="color:#0000ff">1em</span>}<br><br /><span style="color:#a31515">.tag4</span>{<span style="color:#ff0000">font-size</span>: <span style="color:#0000ff">1.2em</span>}<br><br /><span style="color:#a31515">.tag5</span>{<span style="color:#ff0000">font-size</span>: <span style="color:#0000ff">1.4em</span>}<br><br /><span style="color:#a31515">.tag6</span>{<span style="color:#ff0000">font-size</span>: <span style="color:#0000ff">1.7em</span>}<br><br /><span style="color:#a31515">.tag7</span>{<span style="color:#ff0000">font-size</span>: <span style="color:#0000ff">2.0em</span>}<br><br /><br /></p><br /></div><br /></div><br /></div><br /><br /><p>Finally, in our Master page we will call the controller to Render the Partial View TagCloud.ascx and shows us all the tags in the system appropriately weighted:</p><br /><br /><div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:66b0b834-dd9a-44fd-b9c6-d52d257c3164" style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px; padding-top: 5px"><br /><div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"><br /><div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap"><br /><p><br /><br /><span style="color:#0000ff"><</span><span style="color:#a31515">div</span> <span style="color:#ff0000">id</span><span style="color:#0000ff">="tags"></span><br><br /> <span style="background:#ffee62"><%</span><span> Html.RenderAction<SubForum.Web.Controllers.</span><span style="color:#2b91af">ForumController</span>>(c => c.TagCloud());<span style="background:#ffee62">%><br><br /></span><span style="color:#0000ff"></</span><span style="color:#a31515">div</span><span style="color:#0000ff">></span> <br /></p><br /></div><br /></div><br /></div><br /><br /><p>This yields a plain and simple TagCloud looking as such, with the most popular showing first :</p><br /><br /><p><a href="http://lh3.ggpht.com/_N5aAiuG68RA/Sk_kXKK3ALI/AAAAAAAAAYo/rQR-uKB7TUs/s1600-h/image28.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="78" alt="image" src="http://lh6.ggpht.com/_N5aAiuG68RA/Sk_kXW_V_dI/AAAAAAAAAYs/AD8pzU1vvkg/image_thumb16.png?imgmax=800" width="644" border="0" /></a></p><br /><br /><p><strong>Extension</strong></p><br /><br /><p>The Tag Cloud can be extended by limiting the Tags to a predefined set of tags instead of making it free for all. That can simply be done by adding a Tags table which holds all the system’s predefined Tags and only allowing users to pick from those tags. The overall working of this code and the SQL would not be affected at all.</p><br /><br /><p>You can also return the top 10 or however many tags that you want to be displayed instead of displaying all the tags by simply adding a Top clause to your query:</p><br /><br /><pre><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Select&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Select</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Top&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Top</a> 10 <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Count&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Count</a>(1) <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=As&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">As</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Count&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Count</a>, PostTags.Tag <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=As&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">As</a> Tag, (<a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Select&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Select</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Count&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Count</a>(*)<br /> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=From&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">From</a> Posts) <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=As&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">As</a> TotalPosts<br /><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=From&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">From</a> PostTags<br /><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Group&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Group</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=By&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">By</a> PostTags.Tag<br /><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Order&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Order</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=By&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">By</a> '<span style="color: #8b0000">Count</span>' <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&siteid=us%2Fdev&p=1&nq=NEW&qu=Desc&IntlSearch=&boolean=PHRASE&ig=01&i=09&i=99">Desc</a></pre><br /><br /><p><strong>Conclusion</strong></p><br /><br /><p>With this approach all the code from the UI layer including the CSS down to the Data Layer is shown. The approach is universal to any database engine or provider you may want to use and there is nothing hidden except the workings of the MVC Framework. You can see a live demo (if it is up :) ) at <a href="http://www.PortaltoolBox.net">www.PortaltoolBox.net</a> or checkout the actual source on <a href="http://www.subforum.net">www.subforum.net</a>.</p> Adnan Ahmadhttp://www.blogger.com/profile/01008287176974220401noreply@blogger.com7tag:blogger.com,1999:blog-134352470375907644.post-57227729832261312202009-06-22T20:11:00.001-07:002009-06-22T21:22:16.983-07:00The Only Pattern for Data Access is - There Are No Patterns for Data Access<p>Over the years of software development, one thing that has eluded most developers is Data Access. Yes, I mean writing code that accesses a database from your application. It is an age old problem since the days when data storage and computing were invented.</p> <p>We would have thought that by now we would have been able to come up with a clean universal pattern for data access such as the M-V-C pattern for User Interfaces or the Singleton pattern or the Factory pattern. Yet, today we find ourselves with a plethora of technologies and patterns that are constantly struggling to survive to the next release. Just ask yourself, how many iterations of the ORM paradigm have come and gone?</p> <p><strong>J2EE with EJBs and Hibernate must be the answer!</strong></p> <p>In the JAVA world the creation of EJBs, Hibernate and its adoption into the J2EE spec surely would have put an end to the Data Access Layer misery developers faced. But it soon got notorious for being overly complicated, bloated and expensive to develop and maintain. Developers found that it was easy to run queries or stored procedures straight against their databases and get their data directly. Many of them did so in shame and said to themselves, this is hack but ORM way is really the true way. It became obvious when they ran their applications that that their apps ran better, faster and were easier to read without using the full EJB functionality.</p> <p><strong>The notoriously heavy datasets</strong></p> <p>At one time it seemed like Microsoft with their DataSets had won over the Database access world by providing simple disconnected objects that were easily bound to UI’s and were able to do queries to the database or even in memory when they were loaded. But alas they became notoriously heavy, hard to maintain and transport and had to be revamped. Microsoft has dabbed with many iterations of Data Access Layers including Object Spaces, Active Recordsets, LINQ to SQL and Entity Framework. Some of these are still in the market trying to survive like LINQ to SQL, some have become part of history like Active Recordsets and some never made it into sight like Object Spaces and some claim to take over the future like Entity Framework! </p> <p><strong>Why do none of the Data Access Layer Patterns work?</strong></p> <p>In my opinion after having used and worked on many projects that use the above mentioned technologies, <em>the only pattern I see is a pattern of failure</em>. The reason is that these technologies try to mimic the database. They make it look like the user is abstracted from the database by doing what a database does instead of abstracting what a database should do. They completely miss the concept of abstraction. When I abstract something in my code, the job of that abstraction is to hide the internal complexity of something, not repeat the actual work of what I am abstracting. </p> <p>Failed data access layers abstract the database by repeating the work of databases. That is the number one rule of failure. How so you maybe asking. You may say, I love writing my LINQ queries and not having to worry about SQL. The problem begins right there. ORM data access implementations have to implement their own query language! If you have to implement your own query language you are venturing into the complex world of set theory and relational tuples. You better be as good and as fast as a database engine on that or else you will soon be history.</p> <p><strong>The Pattern of Redundancy instead of Abstraction</strong></p> <p>Caching database data in memory is another database copy-cat feature. You better provide better caching, latency, and redundancy algorithms than the database or you are going to face the wrath of the Database Engine pretty soon! I doubt any Data Access technology can beat the caching of query execution plans and caching recently used data provided by the leading database engines such as the commercial engines like Oracle and SQL Server or even the free ones like MySql. Database caches work better even over the network in the long term than the most powerful Object caching providers I have worked with. </p> <p>These features of database access patterns or technologies do not do justice to the database engines they try to tame and therefore soon get bypassed and blown away to their competitor: the no data access layer pattern.</p> <p><strong>What is the no data access layer pattern?</strong></p> <p>The no data access layer pattern is simple; access or persist your data through the native database provider, using the native query language of database engine (SQL). If you stick to this pattern you will be more successful than not in your applications! The only rule of abstraction that you should follow is use data access to populate only application objects that need to be populated or persisted from your application and you should be good. Nothing more nothing less!</p> <p>Let’s take an oath to ourselves and say, <strong>“<em>Thou shall not be fooled by another Data Access Pattern or technology!”.</em></strong> It is like looking for the Abominable snowman. If there was any truth to it we would have found it by now.</p> <a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2ftheahmadblog.blogspot.com%2f2009%2f06%2fonly-pattern-for-data-access-is-there.html"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2ftheahmadblog.blogspot.com%2f2009%2f06%2fonly-pattern-for-data-access-is-there.html" border="0" alt="kick it on DotNetKicks.com" /></a> | <a rel="nofollow" href="http://www.dotnetshoutout.com/submit?url=http%3a%2f%2ftheahmadblog.blogspot.com%2f2009%2f06%2fonly-pattern-for-data-access-is-there.html"> Shout it!</a> Adnan Ahmadhttp://www.blogger.com/profile/01008287176974220401noreply@blogger.com18tag:blogger.com,1999:blog-134352470375907644.post-25986712252878199662009-06-17T05:08:00.001-07:002009-06-17T05:14:34.633-07:00Regional Conflicts<p>We have all come to love our IDE features and take them for granted nowadays. Features like intellisense, code-complete, refactoring and code organization and of course the use of Regions.</p> <p>The #region and #endregion keywords basically provide the ability to hide code and collapse it into a short word or phrase provided at the beginning of the block with the IDE showing a plus sign to expand and collapse the region.</p> <p>Eg: #region Public Methods</p> <p>      #endregion</p> <p>While regions are handy and have become popular, I use them myself occasionally. I don’t particularly fancy them, neither do they improve my code’s readability by much. I believe in keeping my code concise, using descriptive names for methods, classes, variables, etc. and keeping my classes short and easy to read. But sometimes a region for collapsing those using statements and grouping similar methods like constructors, private variables and properties, disposing, etc comes handy.</p> <p>As regions help you “hide” your code some developers like to abuse it to hide shameful code. </p> <p>Let me share with you an example I saw recently. Here the developer is mapping data from his objects to an external system based on keys. The code for this method went of for a few hundred lines of code having a mapping for every field the external system needed.</p> <pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> GetMapDataValue(<span style="color: #0000ff">string</span> key, Account accountObject) <br /> {<br /><br /> <span style="color: #0000ff">switch</span> (key) <br /> { <br /> #region Account Data<br /><br /> <span style="color: #0000ff">case</span> "<span style="color: #8b0000">AccountFirstName</span>": <br /> <span style="color: #0000ff">case</span> "<span style="color: #8b0000">FirstName</span>": <br /> <span style="color: #0000ff">return</span> accountObject.FirstName;<br /><br /> <span style="color: #0000ff">case</span> "<span style="color: #8b0000">AccountLastName</span>": <br /> <span style="color: #0000ff">return</span> accountObject.LastName;<br /><br /> #endregion<br /><br /> #region Address Data<br /><br /> <span style="color: #0000ff">case</span> "<span style="color: #8b0000">AddressLine1</span>": <br /> <span style="color: #0000ff">return</span> accountObject.PrimaryAddress.Line1;<br /><br /> <span style="color: #0000ff">case</span> "<span style="color: #8b0000">AddressLine2</span>": <br /> <span style="color: #0000ff">return</span> accountObject.PrimaryAddress.Line2;<br /><br /> <span style="color: #0000ff">case</span> "<span style="color: #8b0000">AddressCity</span>": <br /> <span style="color: #0000ff">return</span> accountObject.PrimaryAddress.City;<br /><br /> <span style="color: #0000ff">case</span> "<span style="color: #8b0000">AddressState</span>": <br /> <span style="color: #0000ff">return</span> accountObject.PrimaryAddress.State;<br /><br /> <span style="color: #0000ff">case</span> "<span style="color: #8b0000">AddressZip</span>": <br /> <span style="color: #0000ff">return</span> accountObject.PrimaryAddress.Zip;<br /><br /> #endregion<br /><br /> ……<br /><br /> }<br /><br /> }</pre><br /><br /><p>After collapsing the regions, the code looks like this:</p><br /><br /><p><a href="http://lh4.ggpht.com/_N5aAiuG68RA/SjjcuK4PeBI/AAAAAAAAAXo/owPuA1sieLg/s1600-h/image5.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="243" alt="image" src="http://lh5.ggpht.com/_N5aAiuG68RA/Sjjcuk-uoSI/AAAAAAAAAXs/G5lObU_9u5I/image_thumb2.png?imgmax=800" width="623" border="0" /></a> </p><br /><br /><p>This clearly shows that the developer is trying to write separate methods for mapping different pieces of data but instead choose to shove all the code in a switch case statement broken up into different regions for each specific piece of information. It may look organized but in reality it’s a poorly designed function that has been “regionized” to look readable. A classic case of hiding your dirty laundry in the closet.</p><br /><br /><p>Another strange use of regions I have seen over the years since regions have been around is the use of regions as grouping methods as if they were writing classes. This is a classic example from my procedural programmer friends who really have not gotten on the Object Oriented boat that left the shore a long time ago!</p><br /><br /><p>Here is an example:</p><br /><br /><pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> DataAccess<br /> {<br /> #region Account Data<br /><br /> <span style="color: #0000ff">public</span> InsertAccount(Account account)<br /> {<br /> }<br /><br /> <span style="color: #0000ff">public</span> DeleteAccount(<span style="color: #0000ff">long</span> accountId)<br /> {<br /> ...<br /> }<br /><br /> <span style="color: #0000ff">public</span> UpdateAccount(Account account)<br /> {<br /> ...<br /> }<br /> <br /> #endregion<br /><br /> #region Order Data<br /><br /> <span style="color: #0000ff">public</span> InsertOrder(Order order)<br /> {<br /> ...<br /> }<br /><br /> <span style="color: #0000ff">public</span> DeleteOrder(<span style="color: #0000ff">long</span> orderId)<br /> {<br /> ...<br /> }<br /><br /> <span style="color: #0000ff">public</span> UpdateOrder(Order order)<br /> {<br /> ...<br /> }<br /> <br /> #endregion<br /><br /> ... you <span style="color: #0000ff">get</span> the point ...<br /> }</pre><br /><br /><p>A class like this went on for the few hundred objects in the system that needed to be persisted and was no less than 10,000 lines of code! The developer boasted the code to his colleagues and marveled at it. I remember working on this code file. It was so big that even the intellisense started to choke up. When I typed ‘this’ and hit the period key it caused the machine to run on overdrive for a few seconds before the list showed up! Now that is some serious regioning!</p><br /><br /><p>I don't want to give directions on how to use regions but I will say that if you design your code well and make sure your program functionality is broken down in to understandable, re-usable and maintainable classes you will find that your code does not need to be regionalized much. Short concise classes broken down into short descriptive methods will take you far in keeping your code organized and readable. By default the IDE makes methods, classes, and namespaces into regions and that should be enough for the majority of the code you will write!</p> Adnan Ahmadhttp://www.blogger.com/profile/01008287176974220401noreply@blogger.com3tag:blogger.com,1999:blog-134352470375907644.post-51317330466200480822009-06-05T18:02:00.000-07:002009-06-14T13:40:40.172-07:00Var Wars – Abuse of the CSharp var<p> </p> <p>CSharp 3.0 introduced the var keyword for declaring variables without having to explicitly specify the type. This was done for using anonymous types returned from LINQ queries. Now, I am seeing many developers use it all over their code and think its a good thing. </p> <p>Wasn’t C# developed to enforce strongly typed programming? </p> <p>Var just makes it harder to infer the type when reading and maintaining code. </p> <p>Take for example this LINQ Query:</p> <pre class="csharpcode">var user = from u <span class="kwrd">in</span> Users <span class="kwrd">where</span> user.Status == UserStatus.Active<br /> select u;</pre>It is hard enough to infer the type from the above query, let alone infer the type from a statement like this:<br /><pre class="csharpcode">var index = 1; (Is index an <span class="kwrd">int</span>, <span class="kwrd">long</span>?)</pre>Just because a compiler can infer the type does not mean a human should have to be forced to do it when reading it. If we wrote code just to make compilers happy we should be writing Assembly. Why then use an Object Oriented Language? But since code is written for developers to be able to read and maintain it and not just for compilers to compile it, it should be as descriptive and readable as possible.<br /><p>Some say it cuts down on repetitive code when used in a statement like this: </p><pre class="csharpcode">var user = <span class="kwrd">new</span> User();<br /></pre><p>For those who are so obsessed with cutting down characters and lines of code, here is a small piece of advice that will better save you coding time and characters: focus on better design and architecture. If you are so concerned about repetitive code – your energy will be well rewarded. Well designed code is always shorter, cleaner, easier to read and also works better! </p><p>Cutting down on type names is like removing the wrapper from a drink. You have to infer what is in it by drinking it. For those who don’t care about their calories go ahead, but for the rest us, please put the wrappers! </p>The only time you really have to use var is for anonymous types. There is no other way to get an anonymous type. For everything else a type name can and should be used for variable declaration.<br /><p>So for those var abusers, spare the rest of us some inferring and just declare your variables with a type name.</p>Adnan Ahmadhttp://www.blogger.com/profile/01008287176974220401noreply@blogger.com9tag:blogger.com,1999:blog-134352470375907644.post-21381543977793929112009-06-04T04:54:00.001-07:002009-06-05T18:16:18.942-07:00Welcome<p>Welcome to my blog. You may have read some of my postings at <a href="http://www.orasissoftware.com/blog">www.orasissoftware.com/blog</a> or <a href="http://stackoverflow.com/users/45518/ahmad">StackOverflow.com</a> talking about data access technologies, ORMs and code generation. I will continue to blog from now on on this site. I also will guest blog on <a href="http://www.wijix.com/">http://www.wijix.com/</a> whose site and concept I really like; it has many useful, well written utilities and code snippets for programmer’s use.</p><p>Although I don’t want limit myself to blogging on any particular topic, I will promise one thing that you will find on this blog. Everything will be original, informative, unique in perspective and always with a critical eye. I like to raise the bar when it comes to software development. No company or technology is too big or too good to be criticized and challenged! So subscribe now and be part of the conversation!</p>Adnan Ahmadhttp://www.blogger.com/profile/01008287176974220401noreply@blogger.com3