<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Agile smagile! - Forritun</title>
    <link>http://blog.sprettur.is/</link>
    <description>...við eigum brekku eftir, hún er há.</description>
    <language>en-us</language>
    <copyright>Sprettur þróun ehf.</copyright>
    <lastBuildDate>Sun, 24 Jan 2010 23:48:53 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.1.8102.813</generator>
    <managingEditor>info@sprettur.is</managingEditor>
    <webMaster>info@sprettur.is</webMaster>
    <item>
      <trackback:ping>http://blog.sprettur.is/Trackback.aspx?guid=09f0d133-58f2-4b08-8e27-94fdcdf3be58</trackback:ping>
      <pingback:server>http://blog.sprettur.is/pingback.aspx</pingback:server>
      <pingback:target>http://blog.sprettur.is/PermaLink,guid,09f0d133-58f2-4b08-8e27-94fdcdf3be58.aspx</pingback:target>
      <dc:creator>Petar Shomov</dc:creator>
      <wfw:comment>http://blog.sprettur.is/CommentView,guid,09f0d133-58f2-4b08-8e27-94fdcdf3be58.aspx</wfw:comment>
      <wfw:commentRss>http://blog.sprettur.is/SyndicationService.asmx/GetEntryCommentsRss?guid=09f0d133-58f2-4b08-8e27-94fdcdf3be58</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <img src="http://www.clipartguide.com/_small/0512-0807-2115-5744.jpg" alt="Injections can hurt" position="right" border="0" height="175" width="120" />
        <p>
          <a href="http://blog.objectmentor.com/articles/category/uncle-bobs-blatherings">Uncle
Bob</a> posted what was considered a rather <a href="http://blog.objectmentor.com/articles/2010/01/17/dependency-injection-inversion">controversial
blog post</a>, which basically pointed that just because <a href="http://en.wikipedia.org/wiki/Dependency_injection">Dependency
Injection</a> is a good thing, does not mean you cannot shoot yourself in the foot
with the DI framework. He drew attention to the fact that these frameworks in their
desire to be more usable have all kinds of bells and whistles, which you might just
stop and think about before you jump in and start using them.
</p>
        <p>
My initial reaction to this post was very positive since I always have considered
the DI container something external and (potentially) replaceable. Looking from a <a href="http://domaindrivendesign.org/">DDD</a> point
of view (I tend to look from that one, don't I? ;) it is infrastructure which is not
central to my apps, which means it should not be meshed with my core code. Hence my <a href="http://twitter.com/pshomov/status/7902305356">tweet</a>:<br /></p>
        <p>
          <br />
          <img src="http://blog.sprettur.is/content/binary/pshomov%20on%20Twitter.jpg" border="1" />
        </p>
        <p>
        </p>
        <p>
I liked the point he made: you see, you can do Dependency Injection without a container.
I would add, I think everyone who is doing Dependency Injection should do an exercise
once in a while - write a small app without a DI container. There are two points in
this exercise: one - to make sure one remembers the point Uncle Bob made, and two
- to appreciate the DI containers.
</p>
        <p>
Towards the end he says:
</p>
        <blockquote>Most of the time the best kind of Dependency Injection to use, is the
manual kind. Externalized dependency injection of the kind that Guice provides is
appropriate for those classes that you know will be extension points for your system.</blockquote>Not
so sure how I feel about this one though. Most of the time I do use DI container unless
the app is very very small, but unless I try I will never know, right ;)<p></p><p>
Interestingly enough the .NET alpha-geek crowd <a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2010/01/18/poor-use-of-di-versus-need-for-di.aspx">jumped</a>(and <a href="http://ayende.com/Blog/archive/2010/01/22/rejecting-dependency-injection-inversion.aspx">again</a> and <a href="http://davybrion.com/blog/2010/01/dependency-injection-inversion-rejection/">again</a>)
Uncle Bob on this one. Agreed with him for the most part and bashed him for the quote
I just mentioned as well as for his example being too simplistic. I feel they are
being a bit arrogant(bashing the Java tooling and all that) but they do have a point
though. What do you think?
</p><img width="0" height="0" src="http://blog.sprettur.is/aggbug.ashx?id=09f0d133-58f2-4b08-8e27-94fdcdf3be58" /></body>
      <title>Uncle Bob stirs the pot again with "Dependency Injection Inversion"</title>
      <guid isPermaLink="false">http://blog.sprettur.is/PermaLink,guid,09f0d133-58f2-4b08-8e27-94fdcdf3be58.aspx</guid>
      <link>http://blog.sprettur.is/2010/01/24/UncleBobStirsThePotAgainWithDependencyInjectionInversion.aspx</link>
      <pubDate>Sun, 24 Jan 2010 23:48:53 GMT</pubDate>
      <description>&lt;img src="http://www.clipartguide.com/_small/0512-0807-2115-5744.jpg" alt="Injections can hurt" position="right" border="0" height="175" width="120"&gt;
&lt;p&gt;
&lt;a href="http://blog.objectmentor.com/articles/category/uncle-bobs-blatherings"&gt;Uncle
Bob&lt;/a&gt; posted what was considered a rather &lt;a href="http://blog.objectmentor.com/articles/2010/01/17/dependency-injection-inversion"&gt;controversial
blog post&lt;/a&gt;, which basically pointed that just because &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;Dependency
Injection&lt;/a&gt; is a good thing, does not mean you cannot shoot yourself in the foot
with the DI framework. He drew attention to the fact that these frameworks in their
desire to be more usable have all kinds of bells and whistles, which you might just
stop and think about before you jump in and start using them.
&lt;/p&gt;
&lt;p&gt;
My initial reaction to this post was very positive since I always have considered
the DI container something external and (potentially) replaceable. Looking from a &lt;a href="http://domaindrivendesign.org/"&gt;DDD&lt;/a&gt; point
of view (I tend to look from that one, don't I? ;) it is infrastructure which is not
central to my apps, which means it should not be meshed with my core code. Hence my &lt;a href="http://twitter.com/pshomov/status/7902305356"&gt;tweet&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;img src="http://blog.sprettur.is/content/binary/pshomov%20on%20Twitter.jpg" border="1"&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
I liked the point he made: you see, you can do Dependency Injection without a container.
I would add, I think everyone who is doing Dependency Injection should do an exercise
once in a while - write a small app without a DI container. There are two points in
this exercise: one - to make sure one remembers the point Uncle Bob made, and two
- to appreciate the DI containers.
&lt;/p&gt;
&lt;p&gt;
Towards the end he says:
&lt;/p&gt;
&lt;blockquote&gt;Most of the time the best kind of Dependency Injection to use, is the
manual kind. Externalized dependency injection of the kind that Guice provides is
appropriate for those classes that you know will be extension points for your system.&lt;/blockquote&gt;Not
so sure how I feel about this one though. Most of the time I do use DI container unless
the app is very very small, but unless I try I will never know, right ;)&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Interestingly enough the .NET alpha-geek crowd &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2010/01/18/poor-use-of-di-versus-need-for-di.aspx"&gt;jumped&lt;/a&gt;(and &lt;a href="http://ayende.com/Blog/archive/2010/01/22/rejecting-dependency-injection-inversion.aspx"&gt;again&lt;/a&gt; and &lt;a href="http://davybrion.com/blog/2010/01/dependency-injection-inversion-rejection/"&gt;again&lt;/a&gt;)
Uncle Bob on this one. Agreed with him for the most part and bashed him for the quote
I just mentioned as well as for his example being too simplistic. I feel they are
being a bit arrogant(bashing the Java tooling and all that) but they do have a point
though. What do you think?
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.sprettur.is/aggbug.ashx?id=09f0d133-58f2-4b08-8e27-94fdcdf3be58" /&gt;</description>
      <comments>http://blog.sprettur.is/CommentView,guid,09f0d133-58f2-4b08-8e27-94fdcdf3be58.aspx</comments>
      <category>Agile</category>
      <category>Forritun</category>
      <category>XP</category>
    </item>
    <item>
      <trackback:ping>http://blog.sprettur.is/Trackback.aspx?guid=fa3ea5a7-ab11-480d-9289-878c38e994c0</trackback:ping>
      <pingback:server>http://blog.sprettur.is/pingback.aspx</pingback:server>
      <pingback:target>http://blog.sprettur.is/PermaLink,guid,fa3ea5a7-ab11-480d-9289-878c38e994c0.aspx</pingback:target>
      <dc:creator>Petar Shomov</dc:creator>
      <wfw:comment>http://blog.sprettur.is/CommentView,guid,fa3ea5a7-ab11-480d-9289-878c38e994c0.aspx</wfw:comment>
      <wfw:commentRss>http://blog.sprettur.is/SyndicationService.asmx/GetEntryCommentsRss?guid=fa3ea5a7-ab11-480d-9289-878c38e994c0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">I just got off a large project that one
of our customers is running. I will not go into details but it should suffice to say
that it is a rather large multi-phase project that is supposed to create the future
IT backbone for that customer. Before I move on I though I should stop and analyze
what we did right, what went wrong and what can I learn from this experience. And
I thought I would share it with you dear reader ;) 
<br /><br /><b>1. Deploy by the end of the first month to a user</b><br />
In large companies there are usually many reasons why a project cannot be deployed:
dependency on another project which in turn depends on another project and so on,
or someone has to get legal approval for something to be released. Yes, there are
many excuses not to deploy, but in the end that's all they are - excuses. The business
needs to see value, your team needs to get feedback from real users about the system
otherwise you are risking building something no one is interested in and/or the business
people loosing their business patience. My future rule of thumb would be - if you
have not deployed to actual users by the end of the first month of the project, you
need to do get angry and demand this to happen right away.<br /><br /><b>2. Do not accumulate technical debt, push back on Product Owner who does not understand
technical debt</b><br />
Technical debt(from here on referred to as tech-debt) is hard to explain to product
owners that have not programmed. This is understandable and there is no easy way around
it. We tried all kinds of metaphors but I don't think we succeeded in communicating
what tech-debt is and why it is important. The best approach that I can see working
is to negotiate a slice of each sprint to go into paying off tech-debt and demand
extra on top of that at the first sign of trouble. Letting it pile and telling yourself
that it is ok, that you are going to fix it "later" does not work. Never has, not
for me. "Later" the debt is usually so big and the bad stuff has usually spread all
over the place and fixing it becomes an all-or-nothing mini-rewrites that are very
hard to do and are rather unpleasant and unsatisfying experiences.<br /><br /><b>3. Do not allow architectural astronauts to tell you what tools to use</b><br />
It is a strange phenomenon but seems quite persistent: a company becomes mid-sized
and someone decides that now they need to unify "how we do things around here". And
then an Architect (may be even Chief Architect) is appointed who starts googling and
creating a list of tools and technologies allowed to be used. And this is the moment
when you start to be told what tools to use to do your job by the guy who has never
done your job or it has been a while since he has last done your job. Do not let this
happen, say "no" to company politics and demand that you decide what tools to use.
The list of tools should be coming from you and the rest of the guys that are working
in your organization. Architects can be valuable, but this is not the way. Do not
buy into tool vendors based on power point presentations and one day carefully orchestrated
demos from the salesman. You and your peers should be making the standard in your
company. 'nough said.<br /><br /><b>4. Manage expectations so that they are achievable</b><br />
I have come to appreciate marketing as a *very* important aspect of product development.
The same product may be perceived as two complete opposites depending on how its being
marketed. One thing that I've found out is not wise, is to proclaim that your product
will be a universal panacea that will fix all there is to fix. This might sound obvious
and plain common sense, but I am mentioning it for a reason: the larger the promise
you make, the more difficult is to keep it. So I would advise to do small achievable
projects and build software products incrementally and iteratively. And the product
owners have always to be on the lookout how to generate value with minimum effort.<br /><br />
Well, I am off to the new project ... ;)<p></p><img width="0" height="0" src="http://blog.sprettur.is/aggbug.ashx?id=fa3ea5a7-ab11-480d-9289-878c38e994c0" /></body>
      <title>Lessons learnt the hard way</title>
      <guid isPermaLink="false">http://blog.sprettur.is/PermaLink,guid,fa3ea5a7-ab11-480d-9289-878c38e994c0.aspx</guid>
      <link>http://blog.sprettur.is/2009/10/02/LessonsLearntTheHardWay.aspx</link>
      <pubDate>Fri, 02 Oct 2009 22:35:50 GMT</pubDate>
      <description>I just got off a large project that one of our customers is running. I will not go into details but it should suffice to say that it is a rather large multi-phase project that is supposed to create the future IT backbone for that customer. Before I move on I though I should stop and analyze what we did right, what went wrong and what can I learn from this experience. And I thought I would share it with you dear reader ;) &lt;br&gt;
&lt;br&gt;
&lt;b&gt;1. Deploy by the end of the first month to a user&lt;/b&gt;
&lt;br&gt;
In large companies there are usually many reasons why a project cannot be deployed:
dependency on another project which in turn depends on another project and so on,
or someone has to get legal approval for something to be released. Yes, there are
many excuses not to deploy, but in the end that's all they are - excuses. The business
needs to see value, your team needs to get feedback from real users about the system
otherwise you are risking building something no one is interested in and/or the business
people loosing their business patience. My future rule of thumb would be - if you
have not deployed to actual users by the end of the first month of the project, you
need to do get angry and demand this to happen right away.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;2. Do not accumulate technical debt, push back on Product Owner who does not understand
technical debt&lt;/b&gt;
&lt;br&gt;
Technical debt(from here on referred to as tech-debt) is hard to explain to product
owners that have not programmed. This is understandable and there is no easy way around
it. We tried all kinds of metaphors but I don't think we succeeded in communicating
what tech-debt is and why it is important. The best approach that I can see working
is to negotiate a slice of each sprint to go into paying off tech-debt and demand
extra on top of that at the first sign of trouble. Letting it pile and telling yourself
that it is ok, that you are going to fix it "later" does not work. Never has, not
for me. "Later" the debt is usually so big and the bad stuff has usually spread all
over the place and fixing it becomes an all-or-nothing mini-rewrites that are very
hard to do and are rather unpleasant and unsatisfying experiences.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;3. Do not allow architectural astronauts to tell you what tools to use&lt;/b&gt;
&lt;br&gt;
It is a strange phenomenon but seems quite persistent: a company becomes mid-sized
and someone decides that now they need to unify "how we do things around here". And
then an Architect (may be even Chief Architect) is appointed who starts googling and
creating a list of tools and technologies allowed to be used. And this is the moment
when you start to be told what tools to use to do your job by the guy who has never
done your job or it has been a while since he has last done your job. Do not let this
happen, say "no" to company politics and demand that you decide what tools to use.
The list of tools should be coming from you and the rest of the guys that are working
in your organization. Architects can be valuable, but this is not the way. Do not
buy into tool vendors based on power point presentations and one day carefully orchestrated
demos from the salesman. You and your peers should be making the standard in your
company. 'nough said.&lt;br&gt;
&lt;br&gt;
&lt;b&gt;4. Manage expectations so that they are achievable&lt;/b&gt;
&lt;br&gt;
I have come to appreciate marketing as a *very* important aspect of product development.
The same product may be perceived as two complete opposites depending on how its being
marketed. One thing that I've found out is not wise, is to proclaim that your product
will be a universal panacea that will fix all there is to fix. This might sound obvious
and plain common sense, but I am mentioning it for a reason: the larger the promise
you make, the more difficult is to keep it. So I would advise to do small achievable
projects and build software products incrementally and iteratively. And the product
owners have always to be on the lookout how to generate value with minimum effort.&lt;br&gt;
&lt;br&gt;
Well, I am off to the new project ... ;)&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.sprettur.is/aggbug.ashx?id=fa3ea5a7-ab11-480d-9289-878c38e994c0" /&gt;</description>
      <comments>http://blog.sprettur.is/CommentView,guid,fa3ea5a7-ab11-480d-9289-878c38e994c0.aspx</comments>
      <category>Agile</category>
      <category>Forritun</category>
      <category>Scrum</category>
      <category>XP</category>
    </item>
    <item>
      <trackback:ping>http://blog.sprettur.is/Trackback.aspx?guid=6d4c2215-c722-49f6-a4da-5b8ff3003c34</trackback:ping>
      <pingback:server>http://blog.sprettur.is/pingback.aspx</pingback:server>
      <pingback:target>http://blog.sprettur.is/PermaLink,guid,6d4c2215-c722-49f6-a4da-5b8ff3003c34.aspx</pingback:target>
      <dc:creator>Petar Shomov</dc:creator>
      <wfw:comment>http://blog.sprettur.is/CommentView,guid,6d4c2215-c722-49f6-a4da-5b8ff3003c34.aspx</wfw:comment>
      <wfw:commentRss>http://blog.sprettur.is/SyndicationService.asmx/GetEntryCommentsRss?guid=6d4c2215-c722-49f6-a4da-5b8ff3003c34</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In my <a href="http://blog.sprettur.is/2008/11/04/SoftAsInSoftware.aspx" target="_blank">last
post</a> I described my epiphany about the way the business looks at IT (or at least
one very possible look) and left off just before I described the common reasons for
delivering crappy software. So here they come:
</p>
        <ul>
          <li>
Fear of change 
</li>
          <li>
Rigid structure</li>
        </ul>
        <p>
First, and probably foremost, is the fear of change. The uncomfortable feeling every
one of us has felt at one point or another (probably more likely at a lot of points,
but may be that's just me ;) ) in his career when he has to change something in code
that has been in production. Will it work with all the other components that are deployed?
What about the bug that we fixed last month, does it affect the fix in any way? What
will happen if it does not work, can I go back to the old version of the code?
</p>
        <p>
These are all questions which we are often quite uncertain about how to answer. How
can we eliminate this discomfort? 
<br /></p>
        <p>
          <b>By building quality in our products and continuously inspecting them for that quality
- with unit testing, integration testing, and acceptance testing.</b>
          <br />
        </p>
        <p>
Having nailed down the behavior of your software this way gives you a lot of confidence
and eagerness to continue improving and developing your software. Do the green bars
mean that you are 100% safe? Definitely not, but now you have a base which will free
your mind from trying to remember all the little things you need to make sure your
software works as you expect. If you take the time to keep this base growing as your
code grows it will allow you to go quite far. The alternative I have seen is where
you reach a point where you cannot go any further and remain sane, and then it is
time to start over (or the "big refactoring" comes ... ). Time for the bullies to
go asking for investment in rewriting.
</p>
        <p>
Next, the Zen of software development ...
</p>
        <img width="0" height="0" src="http://blog.sprettur.is/aggbug.ashx?id=6d4c2215-c722-49f6-a4da-5b8ff3003c34" />
      </body>
      <title>Soft as in "Software" - part II (The Fear of Change)</title>
      <guid isPermaLink="false">http://blog.sprettur.is/PermaLink,guid,6d4c2215-c722-49f6-a4da-5b8ff3003c34.aspx</guid>
      <link>http://blog.sprettur.is/2008/12/15/SoftAsInSoftwarePartIITheFearOfChange.aspx</link>
      <pubDate>Mon, 15 Dec 2008 23:15:18 GMT</pubDate>
      <description>&lt;p&gt;
In my &lt;a href="http://blog.sprettur.is/2008/11/04/SoftAsInSoftware.aspx" target=_blank&gt;last
post&lt;/a&gt; I described my epiphany about the way the business looks at IT (or at least
one very possible look) and left off just before I described the common reasons for
delivering crappy software. So here they come:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Fear of change 
&lt;li&gt;
Rigid structure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
First, and probably foremost, is the fear of change. The uncomfortable feeling every
one of us has felt at one point or another (probably more likely at a lot of points,
but may be that's just me ;) ) in his career when he has to change something in code
that has been in production. Will it work with all the other components that are deployed?
What about the bug that we fixed last month, does it affect the fix in any way? What
will happen if it does not work, can I go back to the old version of the code?
&lt;/p&gt;
&lt;p&gt;
These are all questions which we are often quite uncertain about how to answer. How
can we eliminate this discomfort? 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;By building quality in our products and continuously inspecting them for that quality
- with unit testing, integration testing, and acceptance testing.&lt;/b&gt; 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
Having nailed down the behavior of your software this way gives you a lot of confidence
and eagerness to continue improving and developing your software. Do the green bars
mean that you are 100% safe? Definitely not, but now you have a base which will free
your mind from trying to remember all the little things you need to make sure your
software works as you expect. If you take the time to keep this base growing as your
code grows it will allow you to go quite far. The alternative I have seen is where
you reach a point where you cannot go any further and remain sane, and then it is
time to start over (or the "big refactoring" comes ... ). Time for the bullies to
go asking for investment in rewriting.
&lt;/p&gt;
&lt;p&gt;
Next, the Zen of software development ...
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.sprettur.is/aggbug.ashx?id=6d4c2215-c722-49f6-a4da-5b8ff3003c34" /&gt;</description>
      <comments>http://blog.sprettur.is/CommentView,guid,6d4c2215-c722-49f6-a4da-5b8ff3003c34.aspx</comments>
      <category>Agile</category>
      <category>Forritun</category>
    </item>
    <item>
      <trackback:ping>http://blog.sprettur.is/Trackback.aspx?guid=42dc8955-a373-4107-a043-400105c6d986</trackback:ping>
      <pingback:server>http://blog.sprettur.is/pingback.aspx</pingback:server>
      <pingback:target>http://blog.sprettur.is/PermaLink,guid,42dc8955-a373-4107-a043-400105c6d986.aspx</pingback:target>
      <dc:creator>Petar Shomov</dc:creator>
      <wfw:comment>http://blog.sprettur.is/CommentView,guid,42dc8955-a373-4107-a043-400105c6d986.aspx</wfw:comment>
      <wfw:commentRss>http://blog.sprettur.is/SyndicationService.asmx/GetEntryCommentsRss?guid=42dc8955-a373-4107-a043-400105c6d986</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
 
</p>
        <p>
          <a href="http://www.developer.com/net/csharp/article.php/3561756" target="_blank">C#
3.0</a> has gotten some great new features that are making the language so much more
expressive. Two of my favorite are <a href="http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx" target="_blank">extension
methods</a> and <a href="http://blogs.msdn.com/ericwhite/pages/Lambda-Expressions.aspx" target="_blank">lambda
expressions</a>. So now, people have started creating all kinds of crazy extension
methods to the built-in type String and every other CLR class. 
</p>
        <p>
Last week I was working on this Java project and doing some logging as part of my
work, and was getting rather annoyed by the idea of having to check the logging level
just before every darn log statement. And then I remembered that the same was true
for the <a href="http://logging.apache.org/log4net/" target="_blank">.NET equivalent
of log4j</a>, but in C# you could do so much better. So I decided to sit down and
get some C# lovin'. First, just to be sure that you dear reader understand what the
issue really is, here is how typical logging is happening using <a href="http://logging.apache.org/log4net" target="_blank">log4net</a>:
</p>
        <p>
          <!--
{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20         \cf3 private\cf0  \cf3 static\cf0  \cf3 void\cf0  LegacyStyle()\par ??        \{\par ??            \cf4 ILog\cf0  logger = \cf4 LogManager\cf0 .GetLogger(\cf3 typeof\cf0  (\cf4 Program\cf0 ));\par ??            \cf3 if\cf0  (logger.IsDebugEnabled)\par ??                logger.Debug(\cf4 String\cf0 .Format(\cf5 "The result of the method is \{0\}"\cf0 , RetrievesSlowData()));\par ??        \}\par ??}
-->
        </p>
        <div style="background: white none repeat scroll 0% 0%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;">
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    1</span> <span style="color: blue;">private</span><span style="color: blue;">static</span><span style="color: blue;">void</span> LegacyStyleOfLogging()
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    2</span> {
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    3</span>     <span style="color: rgb(43, 145, 175);">ILog</span> logger
= <span style="color: rgb(43, 145, 175);">LogManager</span>.GetLogger(<span style="color: blue;">typeof</span> (<span style="color: rgb(43, 145, 175);">Program</span>));
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    4</span>     <span style="color: blue;">if</span> (logger.IsDebugEnabled)
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    5</span>        
logger.Debug(<span style="color: rgb(43, 145, 175);">String</span>.Format(<span style="color: rgb(163, 21, 21);">"The
result of the method is {0}"</span>, RetrievesSlowData()));
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    6</span> }
</p>
        </div>
        <p>
Now, that thing on line 4, that is the nasty check I was talking about earlier. It
is there purely as an optimization in case the debugging level is set to something
higher then "DEBUG" in which case, since the log statement will not be rendered anyway,
the logging string will not be evaluated (you do not know how slow that RetrieveSlowData
method is, looks pretty slow to me ;) ). So all in all, I understand the reasoning,
it's just that I do not want to do it ;). 
</p>
        <p>
Enter extension methods! Without further ado here is my extension method for log4net:
</p>
        <p>
          <!--
{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20     \cf3 public\cf0  \cf3 static\cf0  \cf3 class\cf0  \cf4 LogExtension\par ??\cf0     \{\par ??        \cf3 public\cf0  \cf3 delegate\cf0  \cf3 string\cf0  \cf4 RenderDelegate\cf0 ();\par ??        \cf3 public\cf0  \cf3 static\cf0  \cf3 void\cf0  Debug(\cf3 this\cf0  \cf4 ILog\cf0  log, \cf4 RenderDelegate\cf0  renderer)\par ??        \{\par ??            \cf3 if\cf0  (log.IsDebugEnabled) log.Debug(renderer());\par ??        \}\par ??    \}\par ??}
-->
        </p>
        <div style="background: white none repeat scroll 0% 0%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;">
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    1</span> <span style="color: blue;">public</span><span style="color: blue;">static</span><span style="color: blue;">class</span><span style="color: rgb(43, 145, 175);">LogExtension</span></p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    2</span> {
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    3</span>     <span style="color: blue;">public</span><span style="color: blue;">delegate</span><span style="color: blue;">string</span><span style="color: rgb(43, 145, 175);">RenderDelegate</span>();
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    4</span>     <span style="color: blue;">public</span><span style="color: blue;">static</span><span style="color: blue;">void</span> Debug(<span style="color: blue;">this</span><span style="color: rgb(43, 145, 175);">ILog</span> log, <span style="color: rgb(43, 145, 175);">RenderDelegate</span> renderer)
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    5</span>    
{
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    6</span>         <span style="color: blue;">if</span> (log.IsDebugEnabled)
log.Debug(renderer());
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    7</span>    
}
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    8</span> }
</p>
        </div>
        <p>
So not a lot of code for the extension, basically just an overload of the Debug method
which accepts a delegate as its only parameter. The new overload checks for the DebugLevel
and only then invokes the delegate which is supposed to evaluate the log message.So
let's see how it is being used:
</p>
        <p>
          <!--
{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20         \cf3 private\cf0  \cf3 static\cf0  \cf3 void\cf0  NewShinyStyle()\par ??        \{\par ??            \cf4 ILog\cf0  logger = \cf4 LogManager\cf0 .GetLogger(\cf3 typeof\cf0  (\cf4 Program\cf0 ));\par ??            logger.Debug(() =&gt; \cf4 String\cf0 .Format(\cf5 "The result of the method is \{0\}"\cf0 , RetrievesSlowData()));\par ??        \}\par ??}
-->
        </p>
        <div style="background: white none repeat scroll 0% 0%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;">
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    1</span> <span style="color: blue;">private</span><span style="color: blue;">static</span><span style="color: blue;">void</span> NewShinyStyleOfLogging()
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    2</span> {
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    3</span>     <span style="color: rgb(43, 145, 175);">ILog</span> logger
= <span style="color: rgb(43, 145, 175);">LogManager</span>.GetLogger(<span style="color: blue;">typeof</span> (<span style="color: rgb(43, 145, 175);">Program</span>));
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    4</span>    
logger.Debug(() =&gt; <span style="color: rgb(43, 145, 175);">String</span>.Format(<span style="color: rgb(163, 21, 21);">"The
result of the method is {0}"</span>, RetrievesSlowData()));
</p>
          <p style="margin: 0px;">
            <span style="color: rgb(43, 145, 175);">    5</span> }
</p>
        </div>
        <p>
So now looking at line 4 you can see there is no checking whether the debug level
is "in scope". What you can also see in line 4 is the other new element introduced
in C# 3 that I mentioned earlier - <a href="http://blogs.msdn.com/ericwhite/pages/Lambda-Expressions.aspx" target="_blank">lambda
expressions</a>. They can be automatically converted to delegates and are extra terse
and I think that's what makes this approach feasible. This one has no parameters,
thus the strange looking opening and closing braces before the "=&gt;" signature.
</p>
        <p>
With a little bit more effort one could easily add an exception parameter and implement
all this for the other levels of logging. And all this without modifying the existing
(dare I say ancient) log4net.
</p>
        <p>
You might be wondering if I just put too much effort into saving me a line of code.
For those of you who do, I just have to point out the following benefits:
</p>
        <ul>
          <li>
this line shows up way too often 
</li>
          <li>
there is less noise in my code 
</li>
          <li>
now I can free my mind from having to remember to put in this check 
</li>
          <li>
it is always there, guaranteed</li>
        </ul>
        <p>
So, I wonder how long we will have to wait for JSR-666 that will introduce C# for
the JVM ;)
</p>
        <img width="0" height="0" src="http://blog.sprettur.is/aggbug.ashx?id=42dc8955-a373-4107-a043-400105c6d986" />
      </body>
      <title>Dude, where's my C# for the Java Virtual Machine?</title>
      <guid isPermaLink="false">http://blog.sprettur.is/PermaLink,guid,42dc8955-a373-4107-a043-400105c6d986.aspx</guid>
      <link>http://blog.sprettur.is/2008/09/26/DudeWheresMyCForTheJavaVirtualMachine.aspx</link>
      <pubDate>Fri, 26 Sep 2008 00:35:19 GMT</pubDate>
      <description>&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.developer.com/net/csharp/article.php/3561756" target="_blank"&gt;C#
3.0&lt;/a&gt; has gotten some great new features that are making the language so much more
expressive. Two of my favorite are &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/03/13/new-orcas-language-feature-extension-methods.aspx" target="_blank"&gt;extension
methods&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/ericwhite/pages/Lambda-Expressions.aspx" target="_blank"&gt;lambda
expressions&lt;/a&gt;. So now, people have started creating all kinds of crazy extension
methods to the built-in type String and every other CLR class. 
&lt;/p&gt;
&lt;p&gt;
Last week I was working on this Java project and doing some logging as part of my
work, and was getting rather annoyed by the idea of having to check the logging level
just before every darn log statement. And then I remembered that the same was true
for the &lt;a href="http://logging.apache.org/log4net/" target="_blank"&gt;.NET equivalent
of log4j&lt;/a&gt;, but in C# you could do so much better. So I decided to sit down and
get some C# lovin'. First, just to be sure that you dear reader understand what the
issue really is, here is how typical logging is happening using &lt;a href="http://logging.apache.org/log4net" target="_blank"&gt;log4net&lt;/a&gt;:
&lt;/p&gt;
&lt;p&gt;
&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20         \cf3 private\cf0  \cf3 static\cf0  \cf3 void\cf0  LegacyStyle()\par ??        \{\par ??            \cf4 ILog\cf0  logger = \cf4 LogManager\cf0 .GetLogger(\cf3 typeof\cf0  (\cf4 Program\cf0 ));\par ??            \cf3 if\cf0  (logger.IsDebugEnabled)\par ??                logger.Debug(\cf4 String\cf0 .Format(\cf5 "The result of the method is \{0\}"\cf0 , RetrievesSlowData()));\par ??        \}\par ??}
--&gt;
&lt;/p&gt;
&lt;div style="background: white none repeat scroll 0% 0%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;"&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; LegacyStyleOfLogging()
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(43, 145, 175);"&gt;ILog&lt;/span&gt; logger
= &lt;span style="color: rgb(43, 145, 175);"&gt;LogManager&lt;/span&gt;.GetLogger(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;Program&lt;/span&gt;));
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (logger.IsDebugEnabled)
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
logger.Debug(&lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;.Format(&lt;span style="color: rgb(163, 21, 21);"&gt;"The
result of the method is {0}"&lt;/span&gt;, RetrievesSlowData()));
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6&lt;/span&gt; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
Now, that thing on line 4, that is the nasty check I was talking about earlier. It
is there purely as an optimization in case the debugging level is set to something
higher then "DEBUG" in which case, since the log statement will not be rendered anyway,
the logging string will not be evaluated (you do not know how slow that RetrieveSlowData
method is, looks pretty slow to me ;) ). So all in all, I understand the reasoning,
it's just that I do not want to do it ;). 
&lt;/p&gt;
&lt;p&gt;
Enter extension methods! Without further ado here is my extension method for log4net:
&lt;/p&gt;
&lt;p&gt;
&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20     \cf3 public\cf0  \cf3 static\cf0  \cf3 class\cf0  \cf4 LogExtension\par ??\cf0     \{\par ??        \cf3 public\cf0  \cf3 delegate\cf0  \cf3 string\cf0  \cf4 RenderDelegate\cf0 ();\par ??        \cf3 public\cf0  \cf3 static\cf0  \cf3 void\cf0  Debug(\cf3 this\cf0  \cf4 ILog\cf0  log, \cf4 RenderDelegate\cf0  renderer)\par ??        \{\par ??            \cf3 if\cf0  (log.IsDebugEnabled) log.Debug(renderer());\par ??        \}\par ??    \}\par ??}
--&gt;
&lt;/p&gt;
&lt;div style="background: white none repeat scroll 0% 0%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;"&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;LogExtension&lt;/span&gt;
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;delegate&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;RenderDelegate&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Debug(&lt;span style="color: blue;"&gt;this&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ILog&lt;/span&gt; log, &lt;span style="color: rgb(43, 145, 175);"&gt;RenderDelegate&lt;/span&gt; renderer)
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
{
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (log.IsDebugEnabled)
log.Debug(renderer());
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
}
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&lt;/span&gt; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
So not a lot of code for the extension, basically just an overload of the Debug method
which accepts a delegate as its only parameter. The new overload checks for the DebugLevel
and only then invokes the delegate which is supposed to evaluate the log message.So
let's see how it is being used:
&lt;/p&gt;
&lt;p&gt;
&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof65001\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red163\green21\blue21;}??\fs20         \cf3 private\cf0  \cf3 static\cf0  \cf3 void\cf0  NewShinyStyle()\par ??        \{\par ??            \cf4 ILog\cf0  logger = \cf4 LogManager\cf0 .GetLogger(\cf3 typeof\cf0  (\cf4 Program\cf0 ));\par ??            logger.Debug(() =&amp;gt; \cf4 String\cf0 .Format(\cf5 "The result of the method is \{0\}"\cf0 , RetrievesSlowData()));\par ??        \}\par ??}
--&gt;
&lt;/p&gt;
&lt;div style="background: white none repeat scroll 0% 0%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new;"&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; NewShinyStyleOfLogging()
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(43, 145, 175);"&gt;ILog&lt;/span&gt; logger
= &lt;span style="color: rgb(43, 145, 175);"&gt;LogManager&lt;/span&gt;.GetLogger(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;Program&lt;/span&gt;));
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
logger.Debug(() =&amp;gt; &lt;span style="color: rgb(43, 145, 175);"&gt;String&lt;/span&gt;.Format(&lt;span style="color: rgb(163, 21, 21);"&gt;"The
result of the method is {0}"&lt;/span&gt;, RetrievesSlowData()));
&lt;/p&gt;
&lt;p style="margin: 0px;"&gt;
&lt;span style="color: rgb(43, 145, 175);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&lt;/span&gt; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
So now looking at line 4 you can see there is no checking whether the debug level
is "in scope". What you can also see in line 4 is the other new element introduced
in C# 3 that I mentioned earlier - &lt;a href="http://blogs.msdn.com/ericwhite/pages/Lambda-Expressions.aspx" target="_blank"&gt;lambda
expressions&lt;/a&gt;. They can be automatically converted to delegates and are extra terse
and I think that's what makes this approach feasible. This one has no parameters,
thus the strange looking opening and closing braces before the "=&amp;gt;" signature.
&lt;/p&gt;
&lt;p&gt;
With a little bit more effort one could easily add an exception parameter and implement
all this for the other levels of logging. And all this without modifying the existing
(dare I say ancient) log4net.
&lt;/p&gt;
&lt;p&gt;
You might be wondering if I just put too much effort into saving me a line of code.
For those of you who do, I just have to point out the following benefits:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
this line shows up way too often 
&lt;/li&gt;
&lt;li&gt;
there is less noise in my code 
&lt;/li&gt;
&lt;li&gt;
now I can free my mind from having to remember to put in this check 
&lt;/li&gt;
&lt;li&gt;
it is always there, guaranteed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
So, I wonder how long we will have to wait for JSR-666 that will introduce C# for
the JVM ;)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.sprettur.is/aggbug.ashx?id=42dc8955-a373-4107-a043-400105c6d986" /&gt;</description>
      <comments>http://blog.sprettur.is/CommentView,guid,42dc8955-a373-4107-a043-400105c6d986.aspx</comments>
      <category>Forritun</category>
    </item>
    <item>
      <trackback:ping>http://blog.sprettur.is/Trackback.aspx?guid=55015389-812d-4101-a74d-e24c37cdb911</trackback:ping>
      <pingback:server>http://blog.sprettur.is/pingback.aspx</pingback:server>
      <pingback:target>http://blog.sprettur.is/PermaLink,guid,55015389-812d-4101-a74d-e24c37cdb911.aspx</pingback:target>
      <dc:creator>Petar Shomov</dc:creator>
      <wfw:comment>http://blog.sprettur.is/CommentView,guid,55015389-812d-4101-a74d-e24c37cdb911.aspx</wfw:comment>
      <wfw:commentRss>http://blog.sprettur.is/SyndicationService.asmx/GetEntryCommentsRss?guid=55015389-812d-4101-a74d-e24c37cdb911</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">If one picks any of the popular software
development languages these days he could easily be dazzled by the wide variety of
libraries and frameworks available for that language. In the Java world he would shortly
after be also quite confused since most of these libraries take on the same problem
but each one with its own little twist. That is especially evident when it comes to
UI libraries and frameworks. But what I want to do here is not complain about the
library-per-capita phenomena in Java land, but rather draw your attention to two specific
(and rather well known) libraries and frameworks. The reason I want to do that is
the smooth unobtrusive way they make it easy for me to develop the agile way. 
<p><img src="http://static.springframework.org/images/spring_green_on_white_160x90.png" /> The
first one is the famous <a href="http://springframework.org">Spring framework</a>.
I noticed it has had quite the effect on my mindset while I am writing code. No longer
do I worry about who and how exactly I'm going to get hold of those objects. I <strong>know</strong> it
is not going to be a problem, so I just completely focus on the POJOs and when I have
enough of them ready to do something meaningful, then I wire them up using Spring
and the thing comes in motion very quickly. Another change in my mindset that is a
direct result of using Spring I noticed is I started writing smaller, much more focused
classes. I mean since now wiring them together is so easy I really started doing it
relentlessly. The application ends up usually with just 2-3 lines of Spring specific
code (that is when I am using the Dependency Injection container only, using other
parts of the Spring framework is a different thing) so there are no strings attached
really (no pun intended ;) . I find myself using the <a href="http://static.springframework.org/spring/docs/2.5.x/reference/beans.html">DI
container</a> part of Spring the most, but I use other parts of this excellent framework
occasionally: <a href="http://static.springframework.org/spring/docs/2.5.x/reference/aop.html">AOP</a>, <a href="http://static.springframework.org/spring/docs/2.5.x/reference/orm.html#orm-hibernate">Hibernate
integration</a> and just now - <a href="http://static.springframework.org/spring/docs/2.5.x/reference/portlet.html">Spring
Portlet MVC</a>. These allow for using and learning the framework on-demand and gradually,
no big bang knowledge transfer required. I really like it ;) 
</p><p><img src="http://www.hibernate.org/tpl/hibernate3/img/hibernate_logo.gif" /> The other
library I want to draw your attention to is the no less famous <a href="http://hibernate.org">Hibernate</a>.
The database indifference it provides I find is not its most attractive feature (although
I certainly do appreciate it). Hibernate was the first library I know that successfully
implemented persistence ignorance, allowing me to write the core logic of the application
with no concern for the database. Only after I had a prototype of the system, I decided
to add "real" persistence to a database. With Hibernate it was really easy and more
importantly the patterns that this library is encouraging go a long way towards creating
maintainable applications. And if you are trying to explore <a href="http://www.domaindrivendesign.org/">Domain-Driven
Design </a>(as I am trying to do), Hibernate will fit right in. 
</p><p>
One special note for guys who are doing development in .NET and Java. Since there
are ports of both Spring and Hibernate to .NET, using these frameworks allows for
really nice reuse of knowledge across platforms, something I personally have experienced
since I come to Java from .NET.
</p><img width="0" height="0" src="http://blog.sprettur.is/aggbug.ashx?id=55015389-812d-4101-a74d-e24c37cdb911" /></body>
      <title>Agile developer tooling</title>
      <guid isPermaLink="false">http://blog.sprettur.is/PermaLink,guid,55015389-812d-4101-a74d-e24c37cdb911.aspx</guid>
      <link>http://blog.sprettur.is/2008/08/24/AgileDeveloperTooling.aspx</link>
      <pubDate>Sun, 24 Aug 2008 22:52:39 GMT</pubDate>
      <description>If one picks any of the popular software development languages these days he could easily be dazzled by the wide variety of libraries and frameworks available for that language. In the Java world he would shortly after be also quite confused since most of these libraries take on the same problem but each one with its own little twist. That is especially evident when it comes to UI libraries and frameworks. But what I want to do here is not complain about the library-per-capita phenomena in Java land, but rather draw your attention to two specific (and rather well known) libraries and frameworks. The reason I want to do that is the smooth unobtrusive way they make it easy for me to develop the agile way.  &lt;p&gt;
&lt;img src="http://static.springframework.org/images/spring_green_on_white_160x90.png"&gt; The
first one is the famous &lt;a href="http://springframework.org"&gt;Spring framework&lt;/a&gt;.
I noticed it has had quite the effect on my mindset while I am writing code. No longer
do I worry about who and how exactly I'm going to get hold of those objects. I &lt;strong&gt;know&lt;/strong&gt; it
is not going to be a problem, so I just completely focus on the POJOs and when I have
enough of them ready to do something meaningful, then I wire them up using Spring
and the thing comes in motion very quickly. Another change in my mindset that is a
direct result of using Spring I noticed is I started writing smaller, much more focused
classes. I mean since now wiring them together is so easy I really started doing it
relentlessly. The application ends up usually with just 2-3 lines of Spring specific
code (that is when I am using the Dependency Injection container only, using other
parts of the Spring framework is a different thing) so there are no strings attached
really (no pun intended ;) . I find myself using the &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/beans.html"&gt;DI
container&lt;/a&gt; part of Spring the most, but I use other parts of this excellent framework
occasionally: &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/aop.html"&gt;AOP&lt;/a&gt;, &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/orm.html#orm-hibernate"&gt;Hibernate
integration&lt;/a&gt; and just now - &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/portlet.html"&gt;Spring
Portlet MVC&lt;/a&gt;. These allow for using and learning the framework on-demand and gradually,
no big bang knowledge transfer required. I really like it ;) 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.hibernate.org/tpl/hibernate3/img/hibernate_logo.gif"&gt; The other
library I want to draw your attention to is the no less famous &lt;a href="http://hibernate.org"&gt;Hibernate&lt;/a&gt;.
The database indifference it provides I find is not its most attractive feature (although
I certainly do appreciate it). Hibernate was the first library I know that successfully
implemented persistence ignorance, allowing me to write the core logic of the application
with no concern for the database. Only after I had a prototype of the system, I decided
to add "real" persistence to a database. With Hibernate it was really easy and more
importantly the patterns that this library is encouraging go a long way towards creating
maintainable applications. And if you are trying to explore &lt;a href="http://www.domaindrivendesign.org/"&gt;Domain-Driven
Design &lt;/a&gt;(as I am trying to do), Hibernate will fit right in. 
&lt;/p&gt;
&lt;p&gt;
One special note for guys who are doing development in .NET and Java. Since there
are ports of both Spring and Hibernate to .NET, using these frameworks allows for
really nice reuse of knowledge across platforms, something I personally have experienced
since I come to Java from .NET.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.sprettur.is/aggbug.ashx?id=55015389-812d-4101-a74d-e24c37cdb911" /&gt;</description>
      <comments>http://blog.sprettur.is/CommentView,guid,55015389-812d-4101-a74d-e24c37cdb911.aspx</comments>
      <category>Forritun</category>
    </item>
  </channel>
</rss>