If you have not read about it yet or seen it or used it, please visit Davy Brion’s Blog here and download the Agatha project.  Another link I need to mention is the following, Integrating Strcuture Map With WCF.  Basically what I have attempted to do is create an Agatha.Common.InversionOfControl.IContainer implementation for Agatha which uses StrcutureMap as the IOC Container.  I am also not hosting the WCF Service inside a Web Application but in an actual WCF Service Application which I wanted to use the Service Host Factory as demoed in the above link.

The implementation for the Container was relatively straight forward in most parts and allowed me to use some newer features of StructureMap which I do not currently use yet in my job; well I say newer, newer to me!!.  I have read on Davy Brion’s blog that he is intending to write this Agatha IOC Container for Structure Map, and I look forward to it, but in the mean time I thought I would have a crack at it myself.

While writing the Container for StructureMap I had to make a small change/addition to the Agatha source code, on the interface for the IContainer to make sure that a method had a generic type constraint.  The method:

void Register<TComponent,TImplementation>()

A compile time error was raised which stated that there was no information to allow for boxing/unboxing.  To solve this I added the following constraint:

void Register<TComponent,TImplementation>() where TImplementation : TComponent

Once added the compile time error went, but I was still left with another issue which at this stage of writing this post I am of the opinion that I need to also make a small addition to StructureMap.  I look forward to it, if it is not already available but it would be good to find out that it is already accounted for.  The operation which I am talking about is the removal of an instance from the IOC Container.  The interface for the Agatha IOC IContainer has a method called Release which takes an object instance as a parameter and with the Castle WInsor you can release an instance.

    public interface IContainer
    {
        void Register<TComponent, TImplementation>(Lifestyle lifestyle) where TImplementation : TComponent;
        void Register(Type componentType, Type implementationType, Lifestyle lifeStyle);
        void RegisterInstance<TComponent>(TComponent instance);
        void RegisterInstance(Type componentType, object instance);
        void Release(object component);
        TComponent Resolve<TComponent>();
        object Resolve(Type componentType);
    }

After doing a bit more searching I cannot find a function which fits this criteria exactly.  There is the EjectAllInstancesOf<T> method, but the one I ended up using is the following:

        public void Release(object component)
        {
            //throw new NotImplementedException();
            _strcutureMapContainer.Model.EjectAndRemove(component.GetType());
        }
 

This is a method on the IContainer interface and I am using the component to get its type and releasing all instances of it within the IOC Container.  I am not 100% sure this is what other implementation of IOC are doing with this particular type of function.  Never the less, this does work fine and I am now up and running with the Agatha library inside a WCF Service Application Project using a ServiceHostFactory and configuring a StructureMap IOC Container for use with Agatha.

I have not made the most consistent approach to the StructureMap usage as I have mixed preferred and deprecated methods.  This is because I am not 100% sure how to map the new style of Lifeycle management between Castle Windsor and StructureMap. I look forward to seeing the actual implementation which goes into the Agatha project so I can see where I could have improved my attempt.  Here is the finished code of my attempt.

Hope this is of some help,

Cheers,

Andrew

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using sm = StructureMap;
using Agatha.Common.InversionOfControl;

namespace Agatha.StructureMap
{
    public class Container : Agatha.Common.InversionOfControl.IContainer
    {
        private readonly sm.IContainer _strcutureMapContainer;

        private Dictionary<Lifestyle, sm.InstanceScope> _lifeStyleMappings = new Dictionary<Lifestyle, sm.InstanceScope>
        {
            {Lifestyle.Singleton, sm.InstanceScope.Singleton},
            {Lifestyle.Transient, sm.InstanceScope.Transient}
        };

        private Dictionary<Lifestyle, sm.Pipeline.ILifecycle> _lifeStyleLifeCycleMappings = new Dictionary<Lifestyle, sm.Pipeline.ILifecycle>
        {
             {Lifestyle.Singleton, new sm.Pipeline.SingletonLifecycle()},
            {Lifestyle.Transient, new sm.Pipeline.UniquePerRequestLifecycle()}
        };

        public Container() : this(new sm.Container()) { }

        public Container(sm.IContainer structureMapContainer)
        {
            _strcutureMapContainer = structureMapContainer;
        }

        public void Register(Type componentType, Type implementationType, Lifestyle lifeStyle)
        {
            _strcutureMapContainer.Configure(x => x.For(componentType).LifecycleIs(_lifeStyleMappings[lifeStyle]).Use(implementationType));
        }

        public void Register<TComponent, TImplementation>(Lifestyle lifestyle) where TImplementation:TComponent
        {
            _strcutureMapContainer.Configure(x => x.ForRequestedType<TComponent>()
                .CacheBy(_lifeStyleMappings[lifestyle])
                .TheDefaultIsConcreteType<TImplementation>());
        }

        public void RegisterInstance(Type componentType, object instance)
        {
            _strcutureMapContainer.Configure(x => x.ForRequestedType(componentType).Use(instance));
        }

        public void RegisterInstance<TComponent>(TComponent instance)
        {
            _strcutureMapContainer.Configure(x => x.For<TComponent>().Use(instance));
        }

        public TComponent Resolve<TComponent>()
        {
            return _strcutureMapContainer.GetInstance<TComponent>();
        }

        public object Resolve(Type componentType)
        {
            return _strcutureMapContainer.GetInstance(componentType);
        }

        public void Release(object component)
        {
            //throw new NotImplementedException();
            _strcutureMapContainer.Model.EjectAndRemove(component.GetType());
        }
        
    }
}


.NET | Architecture | C# | WCF
Wednesday, February 10, 2010 10:16:44 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer

Whilst thinking about securing an application and system I am currently building I recalled working with both the eBay and Amazon apis and the security features which they employed and remember thinking how good they were.  Both required token based authentication and more importantly signing each request with a different signature, whilst still maintaining an identity to the service provider which would handle the request.

The idea is rather simple.

You do not want your users downloading a third party piece of software which then asks them for their user name and password in order to use your service.  The security risks of such should be obvious.  The fact is, you want to offer your services for public consumption, but you also want to offer the ability for your services to be used in the context of a different user, again allowing third party software vendors to offer your customers applications they can use against your service.

Tokens

A token, i.e. some string, is used whose meaning is only known between a consumer and the service provider and protected by a secret key again only known between the consumer and the service provider. A few objectives for this type of thing are as follows:

  • A service provider differentiates between each consumer of its public facing service.
    • Not a pre requisite but something that goes hand in hand with the above, is that the service provider records each developer who in turn can create consumers.
  • A service can create a link between existing users and consumers of its public facing services.
  • The identifier of the link between a user and a consumer is absolutely unique. 
    • USER A – CONSUMER A – KEY: A
      USER B – CONSUMER A – KEY: B
      USER A – CONSUMER B – KEY: C
      USER B – CONSUMER B – KEY: D
  • The keys above are for display purposes only just to convey that no link between consumer and user is the same, they are absolutely unique.

My Initial Idea

I want to just put down my initial idea which again is based on both the eBay api and also the Amazon one.  It looks at securing the service against applications and also their use on behalf of users.

The fields involved are as follows:

  • ApplicationID
  • DeveloperID
  • Timestamp
  • UserToken
  • SecretKey
  • Signature

The only thing above which I got from Amazon is the timestamp thing, although it was a while ago when I used it, and I know now that this sort of thing is the norm.  The idea is you take all these values and concatenate them into a string, which you then hash using one of he many hashing or Hmac algorithms, this then forms the signature parameter. What you send to the service is then all parameters barring the SecretKey, which should remain known only to the consumer and the service provider.  Once received the service provider can query its data store for the secret key, hash all the values as the consumer did and make a comparison.  If these match then it can be assumed that the origin of the message is valid.

OAUTH

After more research in to this kind of thing I came across the twitter API which in turn led me to the OAUTH.  If you haven’t yet, then here is the link.

An open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.

And also here which has some great walk troughs of it and process flows:

http://hueniverse.com/2007/10/beginners-guide-to-oauth-part-ii-protocol-workflow/

I am building a custom implementation of the protocol with a couple of demo layers inside Visual Studio 2010, WCF and MVC 2 which I will get on here in the next few days. They offer code in many different flavours to see examples of the protocol but being a protocol, just stick to it, and design it how you like.  That is what I am doing.

My examples will also make use of the previous crypto helper I made, as I think that I will use HMACSHA1 for the signing.  HMACSHA512 sounds a bit large when used in REST implementations. If you do not want to offer a REST implementation then why not go the whole hog and secure using HMACSHA512.

The Example

The example that I am building will be a simple website, which offers users a small service.  It will contain a section for developers to signup with and create an account with which they can create key sets for different applications they make.

Cheers for now,

Andrew


Thursday, November 05, 2009 9:49:36 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer

An extremely important procedure when working with WCF Services or any remote proxy is to close the service when you are finished using it.  I have been working a lot with Structure Map of late as opposed to Microsoft Unity and one thing which I wanted to have a look at was, injecting an instance of the service proxy into my controllers.  Now before I started one thing was circling in my mind, my normal usage when it came to WCF would be that I wrap the proxy inside a using statement, guaranteeing that it would be disposed of correctly. 

Since I am now injecting this service proxy into the constructor, it became apparent that I now needed a finish line where I could dispose of the service proxy after it had been used. Currently, what seems to be working is, as obvious as this sounds, placing the logic inside an override of the base controller’s Dispose method. 

There were a few ideas going through my head but unfortunately this was not sticking out at all, not sure why.  It was only when my attention was brought to the controller factory that it came clear.  The first attempt, which was successful, was to override the ReleaseController method of the Controller Factory.  Inside here I checked whether the controller could be assigned from IDisposable, and if so, cast and call.  This method meant I needed to implement the IDisposable interface on the Controller, well here is something which I SHOULD HAVE KNOWN:

Controller implements IDisposable –> doh! arrghhh

Yeh, not sure why this was not immediately obvious to me but hey ho, you live and learn , so I now removed the unnecessary override inside the Controller Factory and simply override the Dispose method inside the controller. 

        protected override void Dispose(bool disposing)
        {
            (_forumService as IDisposable).Dispose();
            base.Dispose(disposing);
        }

Great stuff, so now when my controller is released my service proxy is also cleaned up.  This is great timing for me and at present works fine.  I am using request/response objects so any information which needs to be dealt with inside a transaction is encapsulated inside the request object which are flat-ISH data transfer objects which can then be processed on the server.

You will notice, or should anyway that without this call to dispose, you wcf service application will not know that the client connection has been terminated.  I have seen that there is obviously a limit to concurrent connections that the service will handle, and when all are in progress, further requests are queued up. Now I have this, and also the service proxy injected, the controller is nice and slick.

Here is an example of what my controller now looks like using the injection of the service proxy:

    public class ForumController : Controller
    {
        private readonly IForumService _forumService;

        public ForumController(IForumService forumService)
        {
            _forumService = forumService;
        }

        public ActionResult Index(int id, int? pageIndex, int? pagseSize)
        {
            var request = new GetForumRequest
            {
                ForumId = id,
                Query = new PagedQueryDto
                {
                    PageIndex = pageIndex ?? 0,
                    PageSize = pagseSize ?? 10,
                    SortOrder = new SortOrderCollection
                    {
                         new SortOrder
                         {
                              ColumnName = "Id",
                              Ascending = false
                         }
                    }
                }
            };

            GetForumResponse response = (GetForumResponse) _forumService.ProcessRequest(request);

            return View(response);
        }

        protected override void Dispose(bool disposing)
        {
            (_forumService as IDisposable).Dispose();
            base.Dispose(disposing);
        }
    }

Once I am further along with more request/response objects I will be putting this sample application up onto Google Code.  This is a project I am deving for the purposes of helping me learn more about Enterprise Architecture with specific focus on the following:

  • Domain Driven Design
  • Domain Events
  • Services
  • Dependency Injection and Inversion Of Control
  • Messaging Systems

Anyways, hope this is of some help,

Cheers for now,

Andrew


Monday, October 12, 2009 12:03:09 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer

I thought I would compose a short how to on programmatic web controls.  Often I have looked at the core set of controls within ASP.NET and wonder what design is required in order to get the design time mark up similar to that of the various controls.  The types of markup I am referring to includes:

  • Containers
  • Lists
  • Templates
  • Nested Controls of a certain type
  • Data bound controls
    • Only one example here, as I have wanted to do for ages and could not quite put my finger on how it was achieved.  Turns out, really simple lol

The following imports are used in these examples:

using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

Simple Container Control

The first custom control structure I want to make is a custom panel.  Not inherited from a panel, although the same would be achieved but rather the simplest custom container. 

Desired Mark up

        <aebs:CustomPanel ID="Panel1" runat="server">
            Hell World
        </aebs:CustomPanel>
This is as simple as it gets.  This is a web control which persists any children controls or elements which you put in side.

    [ParseChildren(false)]
    [PersistChildren(true)]
    public class CustomPanel : WebControl
    {
        public CustomPanel()
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }

A Control with an object list

This control is a web control but it has a list of an object, so you can add numerous types of the object to its collection.  The collection could be of a web control and if so it would be wise to inherit from a composite control as opposed to a web control.

Desired mark-up

        <aebs:ListControl1 ID="ListControl1" runat="server">
            <CustomObjects>
                <aebs:CustomObject CustomProperty="Hello World" />
                <aebs:CustomObject CustomProperty="Hello World 2" />
            </CustomObjects>
        </aebs:ListControl1>

So in design time you will see the intellisense prompt you for a tag called CustomObjects followed by nested prompts of a tag called Custom Object. 

image

    [ParseChildren(true)]
    [PersistChildren(false)]
    public class ListControl1 : WebControl
    {
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public List<CustomObject> CustomObjects { get; set; }

        public ListControl1()
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }

The Custom object is nothing more than a class with a property. see here

    public class CustomObject
    {
        public string CustomProperty { get; set; }

        public CustomObject()
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }

A Template Control

The mark up achieved with this type of control is like the type you see with for example the form view control which allows for:

  • Item Template
  • Insert Item Template
  • Edit Item Template

All I am doing is showing the mark-up required for the design time mark-up, so when using you will need to use the ITemplate InstantiateIn method providing a web control or html control as the container.

Desired mark-up

        <aebs:TemplateControl ID="TemplateControl1" runat="server">
            <HeaderTemplate>
                Hello Header World
            </HeaderTemplate>
            <ContentTemplate>
                Hello Content World
            </ContentTemplate>
            <FooterTemplate>
                Hello Footer World
            </FooterTemplate>
        </aebs:TemplateControl>

image

The code to achieve this is as follows.

    [ParseChildren(true)]
    [PersistChildren(false)]
    public class TemplateControl : WebControl
    {
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate HeaderTemplate { get; set; }

        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate ContentTemplate { get; set; }

        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate FooterTemplate { get; set; }

        public TemplateControl()
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }

You are going to want to control how each template is rendered but for the purposes of this example I am only showing the bare bones of how to achieve the mark-up.

A container control with specific object types as options

A good example of this type of control is when you use the object or sql data source control.  It allows you to specify parameters for the select, insert, update etc…  The options though which are provided to you are restricted so you can only choose parameter objects.  The key here is to specify a list property of the control with the type being a class other inherit from, not necessarily abstract.

Desired mark-up

        <aebs:ConstrainedCollection ID="Constrained1" runat="server">
            <AbstractProperties>
                <aebs:ConcreteOne />
                <aebs:ConcreteTwo />
            </AbstractProperties>
        </aebs:ConstrainedCollection>

image

The code to achieve this mark-up is as follows:

    [ParseChildren(true)]
    [PersistChildren(false)]
    public class ConstrainedCollection : WebControl
    {
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public List<AbstractClass1> AbstractProperties { get; set; }

        public ConstrainedCollection()
        {
            //
            // TODO: Add constructor logic here
            //
        }
    }

So you can see that the only difference between this and the list control example above is that I use a type for the list which is inherited by two other types being ConcreteOne and also ConcreteTwo.

A DataPanel

I have wanted to do this for a while but could not quite put my finger on how it was achieved.  Like I said up top, this turns out to be really simple.  The same could be achieved with an ObjectDataSource and a FormView but i want a light weight container which I could throw an object at and use Eval inside it.  I have many many uses for such a light weight singular object display.  Plus I also wondered how the use of Eval was achieved in Custom Controls, turns out that it is through the use the System.Web.UI.IDataItemContainer Interface.

Desired Mark-up

        <aebs:DataPanel ID="datapanel1" runat="server">
            <%# Eval("ProjectName") %>
        </aebs:DataPanel>

So I am not doing anything more than requesting a property of the object which I throw at the control.  Throwing the object at the control I do inside the Page_Load event just for demo.

    public void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            DataPanel.Project p = new DataPanel.Project();
            p.ProjectName = "Project 101";

            datapanel1.BoundObject = p;
            datapanel1.DataBind();
        }
    }

image

So the code to achieve this is just the simple container control above but this time I implement the interface.  For the purposes of demonstration I have also banged the class inside this type as nested too.

    [ParseChildren(false)]
    [PersistChildren(true)]
    public class DataPanel : WebControl, IDataItemContainer
    {
        public class Project
        {
            public string ProjectName { get; set; }
        }

        private object boundObject;

        public DataPanel()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        public object BoundObject
        {
            set
            {
                boundObject = value;
            }
        }

        #region IDataItemContainer Members

        public object DataItem
        {
            get { return boundObject; }
        }

        public int DataItemIndex
        {
            get { return 0; }
        }

        public int DisplayIndex
        {
            get { return 0; }
        }

        #endregion
    }

Well I hope this is of some use to others,  I will try and update this post soon with examples of custom DataSource controls and also custom DataBound Controls.  When you start get into List Controls from a data source it gets real fun.

Cheers

Andrew



.NET | Architecture | ASP.NET | C#
Tuesday, March 17, 2009 5:47:28 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer

The order in which I am constructing the points of this post are not chronological.  I was told the above statement a couple of years ago by my father who in turn heard it off one of his superiors.  It has taken some time for the actual meaning of this to make sense to me, in that I would see perfection as obtainable, maybe because my idea of perfection is not as high as others.  To rest your mind at ease I discovered that my pursuit of perfection was labour in vain and always will be.

Going completely off track for a second to compound my point, I was thinking of a book I wanted to purchase, which is “The Pragmatic Programmer” I then started thinking, well actually what does pragmatic mean.  So straight on to Google with define:pragmatic and one definition hit a chord straight away and is why this post is titled as it is:

Pragmatism - * In ordinary usage, pragmatism refers to behaviour which temporarily sets aside one ideal to pursue a lesser, more achievable ideal.

en.wikipedia.org/wiki/Pragmatism_(non-technical_usage)

As soon as I read this, the phrase which I was told by my father sprung to mind, albeit worded differently and more academic, but never the less just as meaningful.  I am also a bit surprised that the source of this definition wish to convey that it was not in technical usage.  May be so from a literal stand point, but after all my reading I have been doing of late to become a better programmer, I am thinking TDD, XP, Agile Development, Expectation Management, SCRUM etc… 

One more point I want to insert here, is one which has given me confidence that i am on the correct route in my journey of enlightenment.  In a nutshell I mean the knowledge that “IT IS POSSIBLE YOU MAY BE WRONG.”  I was reading the latest post from Uncle Bob - Let's Hear it for the Zealots! Tue 10/03/2009 21:58 .   Where he states:

There is a difference between a zealot, and a religious fanatic. A religious fanatic cannot envision themselves to be wrong. We in the agile community may indeed be zealots, but we know we can be wrong.

I totally agreed with this and I also paired this with a belief that it is very difficult, probably impossible, to know everything about a topic which fits the following criteria:

  • Large,
  • Diverse
  • Extremely detailed

I would class programming languages in this field as they also improve over time and morph.  .NET versions have gone from 1 to 4 at present, and each build brought new things.  The amount of things to learn in each is immense.  Some information is deprecated while other parts are core and always built on top of.

I will definitely not know everything but I am striving to know as much as I can at any specific time.  This could include information which is of no use what so ever but I want to rely on my growing experience to filter out this kind of information.

Right onto this free chapter of the new ASP.NET MVC 1.0 book released yesterday.

Cheers,

Andrew


Thursday, March 12, 2009 10:19:06 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer

Ok, so there is no doubt that it is difficult to become a software architect and extremely difficult to become a good one.  I read people talking about experience is key, but what about the experience gathered. 

I am developing all the time, and I would class my self as a CAN DO developer who is improving each job that comes.  My issue is my inquisitiveness, in that I might have done something once before, but then I think:

“Hmm ok, but if I do it this way, or If I use this pattern or this method or this technology it will be better | it will be faster OR it will be quite cool to try even if I am unsure of the outcome!”

I have found it extremely stressful, rewarding, tiresome and fulfilling to work for myself, but in the process I have come across so many different ways to, well, SKIN A CAT.  Lets think about Object Relational Mappings ORM, now when you get to this juncture what do you choose:

  1. Create your own, writing it by hand.
    1. Well this sounds fun, but unless you are planning on working with a small data store you have quite a task ahead of you. 
  2. Create a dynamic one through reflection
    1. This is one approach recommended by the Patterns of Enterprise Architecture By Martin Fowler
  3. Create a Code Generation Policy.
    1. Now if you combine the following then you will both learn and have an extremely useful tool in which to create your ORM for present and future projects.:
      1. Point 1 above
      2. A code generation tool e.g. Code Smith
      3. Some time to learn the syntax of the Code Generator
  4. Using a Sub Framework for the ORM e.g. NHibernate, NetTiers, CLSA etc…
    1. Again you would combine this point with a code generator, or you could create by hand.  Would get tedious and prone to human error though
  5. Use ADO.NET
    1. Another option which is recommended by Martin Fowler.  ADO.NET is an extremely powerful way to work with Disconnected Data.
  6. Use LINQ to SQL
    1. Great tool, although I have read that its future is uncertain and the focus will be directed on the ADO.NET Entity Framework.  I love the delayed execution and also the PIPES and FILTERS pattern.
  7. Use the ADO.NET Entity Framework
    1. From my initial exposure, I have found this to be quite amazing.  My first exposure to it has been coupled with ASP.NET Dynamic Data.

So off the top of my head there are 7 points which can also me combined in some cases and these will handle how you communicate to your Data store, quite commonly a database.  BUT WHICH TO USE.   From a risk assessment standpoint, I think it obvious to say that 5, 6 and 7 are the least risk, as in they are tried and tested frameworks from Microsoft themselves with powerful wizards and very little setup and do not require that high a level of knowledge of programming to start using.  Using 4 and 3 together come in next with 1 and 2 bringing the most risk, BUT if you choose 1 or 2 combined with 3 then of course you have the ability to build a complete tailored approach to your Domain Model or SOA.  I am not sure if risk is the correct word, may be complexity and the requirement of experience.  I think that is a better point.

Another point is Test Driven Development.  Purists would say that you should write a test before you create the object which you want to test.  I am find with this, but what if the underlying technology you are getting into is new and you are still un aware of its capabilities.  What do you test, I would need to write some code to see its functionality first and then see where I am at with it.  Once I have an idea of what I can do, then I will then know what to test, so definitely a research stage when pursuing the bleeding edge.

I would love to find out about testing TSQL, as ,my work leads down that route often and sometimes I get stuck with a problem which requires a query that to me, is a head ache.  Ok I want everything from table A and even if it does not exists in Table B with a sub query for the conditional count yada yada yada which involves 5+ tables with complex query parameters.  Then you have the Stored procedures, the scalar, table functions, views, indexes etc…. 

I think my point with this post is the level of learning that you can get drawn into when you dig deep enough, I feel it is like you get to the edge of a cliff, and you are peering over, then all of a sudden WHOOSH, you get blown off the edge and you are surrounded with hoards of material, tutorials, reviews, white papers, books, videos, Do’s, Don’ts, Design, Discussions, Difference of opinions etc….

One thing that is always in the back of my head at the minute is I read a quote from Bjarne Strousup where he says he teaches you how to program and as a by product you learn the language.  I love this quote as it tells me that I can now apply my programming in other languages, and guess what I DO!  What a rant! Right I am signing off.  I found the following image which I thought was extremely good!

 

lightweight-system

SOURCE: http://niksilver.com/

Cheers,

Andrew


Thursday, February 12, 2009 12:43:43 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer