Author Archives: Emad Alashi

Dependency Injection In ASP.NET 5 – One Step Deeper

Dependency Injection has always been an integral part of all the web frameworks under the umbrella of the ASP.NET: Web API, SignalR, and MVC. But historically, these frameworks evolved separately from each other, hence each of these frameworks had its own way of supporting Dependency Injection, even with Katana‘s trial to bring these frameworks together through OWIN, you still needed to do some hackery to have a unified container that supports them all at once. Well, things have changed!

In this post I will dive a little bit deeper than this MSDN post; here we will examine the main interfaces involved, have a small peek inside on how things are running, and explain what it means really to switch to your IoC container of choice.

Abstractions

The decision the ASP.NET team made was to provide the dependency injection functionality through abstracting the most common features of the most popular IoC containers out there, and then allowing the different Middlewares to interact with these interfaces to achieve dependency injection.
ASPNET5 supplies a basic IoC container that implements these interfaces, but also allows the developer to swap this default implementation with their own implementation, through which they can use the IoC container of choice. Usually this is something that is not going to be implemented by the application developer himself rather than something to be implemented by the IoC container maintainers; people behind Autofac, or Ninject…etc.
Having said that, the ASPNET team has provided a basic implementations for the most common IoC containers, but these implementations are most likely to be revised by the IoC maintainers themselves.

Let’s examine the interfaces, shall we?

IServiceProvider

This is the main interface, through which the developer will be able to retrieve the implementation of a service he/she previously registered with the container (we will come to registration later). This interface has one method only: GetService(Type), think of container.Resolve<Service>() in Autofac, or kernel.Get<Service>() in Ninject.

All Middlewares will have access to two IServiceProvider instances:

  • Application-level: made available to the Middleware through HttpContext.ApplicationServices property
  • Request-level: made available to the Middleware through the HttpContext.RequestServices property. This scoped ServiceProvider is created for each request at the very beginning of the request pipeline by an implicit Middleware, and of course this request-level Service Provider will be disposed by the same Middleware at the end of the request just before sending the response back.

Note: I agree, the naming of the ApplicationServices and RequestServices properties might be little bit confusing, but just take it as is for now; these are IServiceProvider.

All the Middlewares will use these properties (hopefully the RequestServices only!) to resolve their services, e.g. the ASP.NET MVC Middleware will create the controllers and their dependencies through the RequestServices (if you don’t believe me check the code, it’s open source ;)), the same goes for creating controllers in Web API …etc.

IServiceScope

Alright, so we said that the RequestServices Service Provider is a scoped container that will be disposed by the end of the request, but how is this managed? You guessed right, by an IServiceScope.

This interface should be a wrapper around a scoped container, whose role is to dispose the container at the end of the request. So naturally it has:

  • IServiceProvider property: the scoped container
  • Dispose() method: by inheriting the IDisposable interface

The question is, who creates the IServiceScope? This brings us to the 3rd interface.

IServiceScopeFactory

Very simple interface as well, it has one method CreateServiceScope() which of course returns a IServiceScope.

So if you maintain an IoC container and you want to use it in place of the default one served by default, you have to implement the above mentioned interfaces.
“But Emad, you didn’t talk about registration of services with the container! And how does it fit all together?!”. Patience my friend, let me just finish this section with the last two classes and then we will jump to the registration.

ServiceLifetime

Enum with 3 keys to define the lifetime of services (objects really):

  • Singleton: single instance throughout the whole application
  • Scoped: single instance within the scoped container
  • Transient: a new instance every time the service is requested

ServiceDescriptor

Finally, the last class! This class is the construct that will hold all the information the container will use in order to register a service correctly; imagine it saying: “hey you, whichever container you are, when you want to register this service make sure it’s a singleton, and take the implementation from this type”. Fancy? Let’s check the members of interest:

  • ServiceType: a property of type Type, this will be the interface for which you will want to substitute with a concrete implementation, e.g. ISchoolTeacher
  • ImplementationType: a property of type Type, this will be the implementation type of the ServiceType above, e.g. SchoolTeacher
  • Lifetime: The lifetime desired for this service: Singleton, Scoped, or Transient.
  • ImplementationFactory: a Func<IServiceProvider, Object>. In some scenarios, the app developer wishes to provide a factory method to instantiate the concrete implementation of the service; maybe there are factors that are outside of the service’s control that mandates how the service should be created, this property will hold this factory method. And yes, it’s mutually exclusive; if you provide an ImplementationType you don’t provide an ImplementationFactory, and vice versa.
  • ImplementationInstance: so you can provide a type as an implementation, and you can provide a factory method to create the object. You also can provide a specific instance, this property of type Object is to hold this instance. Also should be mutually exclusive with the ImplementationType and ImplementationFactory.

Great, now for your application to run as expected, you will have a list of these ServiceDescriptors that you will hand to your container, and tell it to register these services according to how they are described. So let’s look at how this runs together including the registration part.

Registering Services

Now to register your services, ASPNET5 expects that your Startup class has a method called ConfigureServices, it takes a list of ServiceDescriptors, wrapped in IServiceCollection, and returns nothing (there is another form of this method that we will discuss shortly). All what you have to do is to create ServiceDescriptors for the services you want to register and add them to the list. The web app will be pick this list later and then register it with the container.

public void ConfigureServices(IServiceCollection services)
{
var serviceDescriptor = new ServiceDescriptor(typeof(IBankManager), typeof(BankManager), ServiceLifetime.Transient);
services.Add(serviceDescriptor);

// Add MVC services to the services container.
services.AddMvc();
}

Note: Create ServiceDescriptors can be little bit verbose, this is why you see Middleware using Extension methods to create these ServiceDescriptors, like “service.AddMvc()”

So how will this be orchestrated with the application start?

The following pseudo statements explain the server startup and how the Service Provider is created, the corresponding code can be found in the HostingEngine.Start method:

Note: that this post is based on the beta4 version, things have changed since then but the main behavior is the same. So adding the code here won’t add much value; pseudo code should be good enough

  1. Hosting engine will create an IServiceCollection, which is a collection of ServiceDescriptors
  2. Hosting engine will add all the services it needs to the list
  3. Hosting engine will ensure that there is a Startup class in your assembly and that it has a method called ConfigureServices
  4. Hosting engine will load this method and call it passing the IServiceCollection
  5. ConfigureServices in the Startup class will add the apps services to the list
  6. Hosting engine will create a DefaultServiceProvider (the container) and use the information in IServiceCollection to register the services to the DefaultServiceProvider
  7. Hosting engine will create the Application Builder (IApplicationBuilder) and assign the new Service Provider to the property IApplicationBuilder.ApplicationServices so it can use it further down
  8. Hosting engine will add a Middleware before giving the chance for the Startup.Configure to run, placing it to be the first Middleware in the pipeline. The Middleware is RequestServicesContainerMiddleware, which will be discussed shortly.
  9. Hosting engine will call Configure method in Startup class passing the Application Builder to build the Middleware pipeline where the Service Provider can be used through the ApplicationServices property to build the Middleware if needed

Great, the server is configured, started, and ready to receive requests. What happens now in a request? how is the dependency injection is run?

Running a Request

When the request first comes, an HttpContext will be created to be handed to the Invoke method of the first Middleware, and subsequently to all the Middlewares. But just before it’s handed to the first Middleware, the Application Builder’s Service Provider is assigned to the property HttpContext.ApplicationServices, making the application-level Service Provider available through the HttpContext for all the Middleware to use it up to their needs. Though, it should be kept in mind that this is the application-level Service Provider, and depending on the IoC container of choice, your objects might stay alive through the whole lifetime of the application if you use it.

Note: in theory, as an application developer, you should not use the Service Provider directly; if you do then you are doing a Service Locator pattern, which is advised against.

Ok then, that was an application-level Service Provider, isn’t there a Service Provider that is scoped for the lifetime of the request? Yes, there is.

In step 8 in the list above, we mentioned that the hosting engine adds the RequestServicesContaienrMiddleware Middleware at the beginning of the pipeline, giving it the chance to run first.
The code hasn’t change much for this Middleware for a long time, so I think it’s safe to put the code here 🙂

public async Task Invoke(HttpContext httpContext)
{
    using (var container = RequestServicesContainer.EnsureRequestServices(httpContext, _services))
    {
        await _next.Invoke(httpContext);
    }
}

Going back to the request execution, the server creates the HttpContext, assigns the application-level Service Provider to the HttpConext.ApplicationServices, and then invokes the first Middleware, which is the RequestServicesContainerMiddleware. Can you see that using statement in the Invoke method? There where the magic lies; all what it does is that it creates a Scoped Service Provider that will be disposed at the end of the request. The pseudo will be:

  1. Request is handed by RequestServicesContainerMiddleware
  2. Invoke will retrieve an IServiceScopeFactory from the application-level Service Provider via HttpContext.ApplicationServices.
  3. IServiceScopeFactory will create a scoped container (think of ILifetimeScope in Autofac)
  4. The scoped container will be assigned to the property HttpContext.RequestServices
  5. The Invoke method calls the subsequent Middlwares allowing the request to go through
  6. When all the Middlewares are invoked and the call return is back to the RequestServicesContainerMiddleware, the scoped Service Provider will be disposed by the “using” statement.

Note: RequestServicesContainerMiddleware uses a wrapper/helper class RequestServicesContainer to manage the creation and disposition of the scoped Service Provider, which is the object used in the “using” statement really

The HttpContext.RequestServices is the scoped container for the request lifetime, all the subsequent Middleware will have access to it. For example, If you check the MvcRouteHandler.InvokeActionAsync you will see that it’s using it to create the controllers:

private async Task InvokeActionAsync(RouteContext context, ActionDescriptor actionDescriptor)
{
    var services = context.HttpContext.RequestServices;
    Debug.Assert(services != null);

    var actionContext = new ActionContext(context.HttpContext, context.RouteData, actionDescriptor);

    var optionsAccessor = services.GetRequiredService<IOptions<MvcOptions>>();
    actionContext.ModelState.MaxAllowedErrors = optionsAccessor.Options.MaxModelValidationErrors;

    var contextAccessor = services.GetRequiredService<IScopedInstance<ActionContext>>();
    contextAccessor.Value = actionContext;
    var invokerFactory = services.GetRequiredService<IActionInvokerFactory>();
    var invoker = invokerFactory.CreateInvoker(actionContext);
    if (invoker == null)
    {
        LogActionSelection(actionSelected: true, actionInvoked: false, handled: context.IsHandled);

        throw new InvalidOperationException(
            Resources.FormatActionInvokerFactory_CouldNotCreateInvoker(
                actionDescriptor.DisplayName));
    }

    await invoker.InvokeAsync();
}

Note: a reminder, again, you shouldn’t need to use the Service Provider directly; try to manifest your dependencies through constructors, avoid the Service Locator pattern.

Awesome, now what if you want to substitute the default container with something like Autofac? Glad you asked, let’s see how.

Bring Your Own IoC Container

Before we start, this is a reminder that this is something to be implemented by the IoC container maintainers, not by the application developer.

To use your own container you have to implement the interfaces: IServiceProvider, IServiceScope, and IServiceScopeFactory. Implementing the interfaces should be straight forward because the interface itself is mandating what you need to do, the Autofac implementation can be used as an example.

But the subtle thing that needs to be explained that the ConfigureServices method in the Startup class has another form that the hosting engine expects, this form is expected in case the developer wants to use his own IoC container. In this form the method should return an IServiceProvider; once all the desired ServiceDescriptors are added to the IServiceCollection, the developer should create his container, register the services the way the container expects it, and then returns the container’s implementation of the IServiceProvider. The following is the code to use Autofac:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    // Add MVC services to the services container.
    services.AddMvc();

    var builder = new ContainerBuilder();

    // Create the container and use the default application services as a fallback
    AutofacRegistration.Populate(
        builder,
        services);

    var container = builder.Build();

    return container.Resolve<IServiceProvider>();
}

The AutofacRegistration.Populate registers the services the way Autofac likes, and registers the IServiceScope and IServiceScopeFactory implementations (this is only a part, check the complete code on the link):

private static void Register(
ContainerBuilder builder,
IEnumerable descriptors)
{
foreach (var descriptor in descriptors)
{
if (descriptor.ImplementationType != null)
{
// Test if the an open generic type is being registered
var serviceTypeInfo = descriptor.ServiceType.GetTypeInfo();
if (serviceTypeInfo.IsGenericTypeDefinition)
{
builder
.RegisterGeneric(descriptor.ImplementationType)
.As(descriptor.ServiceType)
.ConfigureLifecycle(descriptor.Lifetime);
}
else
{
builder
.RegisterType(descriptor.ImplementationType)
.As(descriptor.ServiceType)
.ConfigureLifecycle(descriptor.Lifetime);
}
}
else if (descriptor.ImplementationFactory != null)
{
var registration = RegistrationBuilder.ForDelegate(descriptor.ServiceType, (context, parameters) =&gt;
{
var serviceProvider = context.Resolve();
return descriptor.ImplementationFactory(serviceProvider);
})
.ConfigureLifecycle(descriptor.Lifetime)
.CreateRegistration();

builder.RegisterComponent(registration);
}
else
{
builder
.RegisterInstance(descriptor.ImplementationInstance)
.As(descriptor.ServiceType)
.ConfigureLifecycle(descriptor.Lifetime);
}
}
}

But then how will this fit with the 9 steps above in Registering Services? Well, it changes a little bit to become like this (red and strike-through’s are the changes):

  1. Hosting engine will create an IServiceCollection, which is a collection of ServiceDescriptors
  2. Hosting engine will add all the services it needs to the list
  3. Hosting engine will ensure that there is a Startup class in your assembly and that it has a method called ConfigureServices. First it will look for the form that returns an IServiceProvider, if not found then it uses the one that returns nothing
  4. Hosting engine will load this method and call it passing the IServiceCollection
  5. ConfigureServices in the Startup class will add the apps services to the list
  6. ConfigureServices will create the IoC container of choice
  7. ConfigureServices will register all the services in the IServiceCollection to the new container
  8. ConfigureService will make sure to register the IServiceScope and IServiceScopeFactory with the services (remember step 2 in Running a Request above?)
  9. ConfigureServices will create an instance of the container’s implementation of the IServiceProvider and return it
  10. Hosting engine will create a DefaultServiceProvider and use the information in IServiceCollection to register the services to the DefaultServiceProvider The Hosting engine will retrieve the IServiceProvider supplied
  11. Hosting engine will create the Application Builder (IApplicationBuilder) and assign the new ServiceProvider to the property IApplicationBuilder.ApplicationServices so it can use it further down
  12. Hosting engine will add a Middleware before giving the chance for the Startup.Configure to run, placing it to be the first Middleware in the pipeline. The Middleware is called RequestServicesContainerMiddleware, which will be discussed shortly.
  13. Hosting engine will call Configure method in Startup class passing the Application Builder to build the Middleware pipeline where the Service Provider can be used through the ApplicationServices property to build the Middleware if needed

Voila! all is ready

Conclusion

I hope by now there is no magic in how dependency injection really works in ASP.NET 5, if you have questions or comments feel free leave it in the comments section.

Tips’n Tricks

  • In order for you debug this whole process and step in the code you need to do two things:
    • Get the code by checking out the repositories from GitHub and make sure you are on one release tag (like beta4)
    • Create a web app in Visual Studio
    • Alter the “global.json” file so you add the paths to the repositories source to the “projects” key like this *
    • Now you have the code in your hands and can step through it
  • Code of interest:

ANZCoders Wrapup

Over the last week, the first ANZCoders virtual conference was taking place, the conference that you can attend in your pyjamas! Fifteen sessions over five days by twelve speakers, all voted upon by the audience themselves.

The conference was live, but it was recorded also on Youtube; every session has its own Youtube video available for watching any time. So I hear you say “Why attend live if the video is going to be available later?!”…here is why:

  1. The live Q & A: after the session the audience was given the chance to ask the speaker questions, just like any real conference; which is something that is not available for people watching the video later.
  2. The live discussion: As the speaker was running through the session, the chat channel was humming with all sorts of different opinions, supporting stories, links to resources, and there lots of laughs that made the conference even more fun! although this might sound distracting a little bit for both the audience and the speaker, but IMHO the benefits overcame the drawbacks.
  3. The people: connecting with such intelligent and passionate people was invaluable! Enough said.

The only drawback I guess was the reliability of the speaker’s internet connection; I for example lost at least 6 valuable minutes of my “IoC in ASPNET5” talk, even with my best arrangements to have proper connectivity! (Yes, you need to skip past the minutes from 2:30 to 8:30). But hey, a speaker can have a flu in face-to-face conferences as well ;).

Will I participate in a live virtual conference again? Absolutely!

So big thanks to Richard Banks for organizing the conference, and big thanks to the sponsors, the speakers, and the lovely audience who made this event a success!

 

Consultant Skills: Self-Confidence

Look into the mirror, Increase self-confidence

I have blogged before about some of the skills that a consultant should be acquainted with like Story Telling, Knowledge Depth & Breadth, and Having an Opinion, all of which I see very important. But in this post I would not hesitate to say that self-confidence is the single most important amongst them all!

Before we continue, what does “self-confidence” mean? my words of choice would be: “it is the belief someone has about his/her capability of accomplishing something that he/she hasn’t tried before“. Notice here that it’s a “belief”

Lacking Self-Confidence Is Bad

“How come you think it is the most important?” I hear you ask. Well, if you have been following my posts you will clearly see that I love bullet points, so let me list how lack of self-confidence is bad:

  • Lack of self-confidence is the chuckles and chains that the individual would willingly put around his neck, preventing himself from achieving even the simplest of goals, even if he has the potentials and capabilities; he might be smart, thoughtful, knowledgeable, and resourceful, but he will not utilize any of these treats because he thinks he doesn’t have them, nill, zero!
  • The main job of a consultant is to solve the problems of his clients; the client is clueless, confused, lost, in doubts, and he needs help, he needs someone to rescue him from the trouble he is in. Imagine yourself to be such a client, would you accept a consultant’s help if he wasn’t in a better state than you are?  if the consultant himself is not sure of his capabilities, he doubts his skills, will you still hand your problem to him to solve?    For employees it might be different; the employee might be considered as an investment the company or management might invest in, so he receives the encouragement and support to get him going, increase self-confidence if he lacks it, consultants on the other hand don’t have this luxury.
  • Even if you are not taking clients, your image seen by people and peers will be affected. People will see you as you see yourself; if you see yourself as someone who can provide solutions and solve problems, you will be looked at as such person, if you see yourself as weak, stupid, or failure then, no surprise, you will be looked at as such person.
  • Self-doubt brings depression, with various of levels, if not controlled.
  • If you find these points aren’t bad enough, then re-read the first point above

OK it’s obvious how tremendously dangerous this is, but how to solve this?

How to Increase Self-Confidence

Shall we list:

  • Acknowledge the problem; this is going to be the driver force of change; realization. You have to realise how big of a problem this is, and realise the grave effect it has on you. This is a state that we should have absolutely zero tolerance with.
  • Remember the “belief” part of the definition? you have to find a proof that supports your belief, why do you think you can’t do it? can you prove that you can’t? I would say help yourself out and whenever you are in doubt try to remember all the success stories and accomplishments you have achieved in your life that can be compared to the situation you are in, and use it as a proof that you can.
    What if you can’t find a proof of success? well, at least you don’t have a proof of failure! so you can’t be doubting yourself!
    What if you DO have a proof of failure? then you should ask yourself: “was it the same circumstances? have I changed since then? is this situation exactly like the one I failed in?” if your answer was no, and most likely it is, then this can’t be used as a proof, and we are back to the fact that you don’t really know if you can’t accomplish! if your answer was yes though, then let’s examine the next point.
  • Ask yourself “what can I do to do things differently this time? How can I change the reason that caused my previous failure, so it is not any more?” and this is a competitive advantage over confident people, you are URGED to think more, try harder, prepare better, and find a better way of doing things. Remember the turtle and rabbit race story?
  • Self-doubt and the fear of failure goes hand in hand; we think we can’t accomplish, consequently we think that if we try we will fail, and failing is a big problem, right? well, no! whenever I am anxious about something, my wise wife asks me “what is the worst thing that can happen?”; we tend to build feelings of fear, based on our implicit imagination, that are much greater than what they would really be if the failure really happens. So thinking about the worst case scenario would invalidate these fears and give them their proper size.
  • In most of the cases, the opportunity cost is much greater than the failure cost. If self-doubt prevented you from trying to take a leading position, then your loss of losing that position is greater than the loss you would have trying and failing (in that attempt); at least you will learn how to do it better next attempt. It might a simple sentence, but think about it for a minute, absorb it…what do you think?

Finally, know that this is a continuous struggle with yourself, this will never end! if you grow you will be exposed to new things, if you are exposed to new things you will doubt yourself, period! hopefully, though, with these tips and tricks you will be in control, you will use your self-doubt to your advantage and move forward successfully.

Now go and nail it!

[Image Credit: Kevin Cawley]

Consultant Skills: Having an Opinion

This is the third of three posts I’ve written about consultant’s skills, check the previous posts if you like:

————-

We work in an industry where one general problem can be solved by too many ways, each emerges from a different mindset and different circumstances. But also, in this industry there is community pressure, there are “cool geeks” and “cool solutions”, there are “best practices”, and there are hypes and fads.

And you guessed right, my dear reader, many of us lease their brains to these influences; if it is individuals, we wait for their blog post or tweets, if it is organizations we wait their radar, or if it is a community we count how many use it, …etc.
And here I would bring up two questions:

  • Why do we do that?
  • And what is the impact of this behavior on us as individual experts, and the industry?

Answering these two questions should positively change the way we think of technology, and how to interact with it. So let’s attempt answering them:

Why do we do that?

Because:

  • Thinking is heavy, and we are lazy! having an opinion about a certain solution, a database engine, an architectural design, or an open source project…having an opinion requires knowledge that needs to be acquired, and requires time to sit and think of all the scenarios in which this solution can be suitable, or not. All of this is heavy and takes a lot of effort, so instead of taking that burden we seek ready answers
  • We are afraid to be judged. I’d want to give an opinion about this framework but I am afraid to criticize it, I want to say that I don’t like it for that reason, but I am afraid that my opinion would turn out wrong, or “stupid” in the eyes of others. So I’d rather keep quiet, right?
  • Lack of self confidence. And this is different from the point (2) above, here I don’t care what others think of me, but I am not sure of my brain capabilities; am I really intelligent enough to judge this framework? we put ourselves down to the extent that we don’t even ask ourselves if we are smart enough or not! We just believe we aren’t, and consequently never think of articulating an opinion at all.

What is the impact of not having an opinion?

  • We become mentally disabled! We become too dependent on others to the extent that we can’t intellectually live on our own. What if circumstances push us to situations where the capability of getting external help is narrow?
  • Opinions supported by proofs drive solutions. If we don’t have opinions we transform from developers to coders, we loose our value as solution providers, which is bad for us economically as the demand on us in the market diminishes, and more importantly bad to our self-respect; what are we other than the value we bring to the world? you must have heard of the “The surprising truth about what motivates us
  • Others give us THEIR solutions, that solved THEIR problems, which will not necessarily solve ours.
  • We damage the industry as we shutdown intellectual power that would’ve enriched the industry, no matter how small that would be.

So, if you agree with me to the points above, then let’s check some of the suggestions that would enable me and you to form opinions, and hopefully good ones.

How to form an opinion?

  • Don’t underestimate your mental capabilities. This is the most important point! At the end of the day it’s mere logic, and we all have logic; in general fast is better than slow, simple is better than complex, cheep is better than expensive, …etc.
  • Try answering your own questions. For example, you see more ORMs coming to existence and more people using them, you used it yourself, but you never had an opinion about them. One time you wonder if they really provide a value, or if they are just a waste, so you instantly think of your really smart colleague, he must have an answer. My suggestion to you is just before you ask him, try to answer the question yourself; doing so explicitly will force you to think, you might surprise yourself!
  • Learn from others, observe their opinions. And no, I am not saying to adopt their opinion, what I am saying is that forming an opinion is a skill that can be learned. Check how they approach the product, what they see as weaknesses and why, and what they see as power and why. The better you observe smart people’s opinions, the better you can form one
  • Acquire and then utilize knowledge. In order to form an opinion about something you have to know something about it! the more you know, the closer to being correct your opinion is, so you better do your homework and acquire knowledge as much as you can. Of course up to some point you will not have the time, capacity, or resources to know more, in that case you build it according to the knowledge you accumulated, the catch here though is to declare that amount of knowledge when you give your opinion.

Caveats

  • We still need to ask experts. In fact, I even encourage you to do so, but the only thing I am asking is not to follow it blindly! The idea here is to be able to judge for ourselves which solution is more solid than another using our own logic, even if it means we have to weigh between experts opinions.
  • You don’t have to have an opinion about everything, but at least on things that affect your technical life.

Conclusion

You want to be more valuable? You want to grow your career? You want to be independent? Then have an opinion.

9 Things I Learned From Skiing

I had the opportunity to visit Mount Buller to do skiing for the first time in my life (thanks to Joshua McKinny), and the experience was UNBELIEVABLE! In addition to the loads of fun I had, I learned some life lessons that can be applied in any field, even software! and I’d like to share with you.

buller

  1. When in doubt, get rid of doubt.
    A night before the trip, I was at the shops. I saw this winter warm hat that I thought I should buy, then I remembered I had one at home but I wasn’t sure if I still had it; I remembered one time when I needed it and I couldn’t find it, so I had doubts!
    I had to take a decision, something like the following diagram:

    Apparently possibility D has a much higher cost compared to any A, B, and C. And the only way to avoid it is to take decision X rather than Y… I chose Y, and ended up with D!
    At the end I managed, but let’s just say I was left in an embarrassing situation.
  2. Everything has pros and cons
    Between choosing Skiing and Snowboarding, I chose Skiing; the majority of opinions was that Skiing is easier and you have more control, which is better for beginners. But this came with a cost; the boots were horrific to walk with, and I had to carry two sliders and two poles all around! I don’t regret my choice, but let’s say I am a lot more aware that there are cons with every choice we make, the question is are we willing to make the most of it or not.
  3. Listen to the experts
    Josh gave us of a long list of advice beforehand; what stuff to bring along, where to get the gears from, what we should expect…, all of which made a huge difference. And whenever you fail to listen you are beaten, I will never forget a scarf when I am at the top of the mountain!
  4. It’s more difficult than I thought
    I judged Skiing too early, from the videos and photos I have seen in my life, it seemed too easy! just go in angles and change the direction once you reach the edge of the slope, and repeat until you reach the end. Guess what? Easier said than done!
    Skiing literally is sliding on a slippery surface, while you try your best to control sliding; the sliders are long, heavy, and go in all directions, the amount of effort you have to give to control the sliders to go in a certain direction is big, and they don’t just listen! the angles in which you have to position them to accomplish that control is tricky, the pressure on your knees is enormous, your body’s position makes a big difference, and the slightest loss of control of the sliders your body will start wobbling, and you don’t just cross your legs to fix that! Oh and did I mention that there are types of snow, some of which makes things even harder?…ENHALES!
    The idea of this lesson, don’t just underestimate and judge too quickly, anything, unless you try it out first.
  5. You don’t know what you are missing, until you try it. It’s loads of fun!
    Sometimes we are just too lazy, and due to our laziness (or let’s say “comfort zone”) we miss out on too many opportunities. I knew that it’s going to take me a day, and it’s going to be cold, and I have to learn skiing, and was afraid that I wouldn’t enjoy it…but…I pushed myself; I also knew that this is not going to happen again anytime soon and should tick it off my bucket list, let me tell you this: IT WAS AWESOME! Doing it myself revealed many aspect I’d never get from watching a video, the mere speed a human can reach on these sliders is of utmost thrill, let alone the joy when you really start controlling it.
    It really made me think of all the things I might be missing due to the same reason, whether it was leisure or career opportunities
  6. You are going to fall, and it’s going to hurt
    There is absolutely no escape from falling, unless you are an expert, than you already have fallen plenty of times, and to the surprise, it hurts! I fell so many times: one time on my arm which ended up swollen, one time twisted my leg, and another time was displaced couple of meters away from my slider after it flew off.
    These falls were necessary; I knew exactly what to do, and what NOT to do, because I didn’t only “hear” about the consequences, I lived them, and they hurt! So because of these falls I had to learn, because of these falls I became a better skier
  7. In fact pain is part of the fun
    The falls mentioned in point 5 were painful indeed, but they also were fun; it breaks the routine of the body, the monotonous experience we go through in our lives, being thrown and twisted in the air, and feeling your body going through a different experience, all of this had its flavor, it might be funny, but it really did (don’t break something while you do that).
    But more important than that, these falls also gave a better meaning for success; when I slide for longer periods without falling, the feeling of success I have is deep, and meaningful. If it was too easy that success would taste like…meh.
  8. Following instructions is important, but so is following instinct
    I had a lesson by an instructor for I am an absolute newbie, the instructor gave us the instructions on how to stop and manuever, along with some other instructions, and then released us to the wild. I tried to follow all his instructions perfectly, usually I am a good student, but I still kept falling!
    Then at one of the slopes I felt like I should be leaning my body in a certain angle, and press with my toes down, it was an absolutely instinctive feeling, not a trial and error thing, and guess what…it worked! the instructor didn’t mention this; maybe because he never really gave it a deep thought, maybe he has been skiing all his life, regardless of the reason, he gave me instructions that weren’t enough, I had to use my instinct that proved highly valuable in addition to the external knowledge.
  9. Most importantly, company is everything
    This, my dear reader, was of the utmost importance; Josh and Neil were extremely good company, very understanding, patient with my primitive skiing skills, easy going with suggestions, generous, and full of knowledge that filled the trip with beneficial discussions. All of which allowed me to enjoy things enough to come up with the previous 8 lessons!

Did I learn more lessons? indeed, but 9 is a nice number 😉

 

NOT Another Post About Estimation

I was involved in a project that was given 10 days to finish, the tight schedule was due to budget reasons.

The client explained to me his requirements and then asked for an estimate for details. We stood in front of the whiteboard, broke down the features and then started estimating the time for these features, until we reached feature x.

In my technical life I’ve been beaten by over-simplified requirements far too many times, so as simple as feature x sounded I strongly felt that it might stretch. Subsequently, this influenced my opinion of giving feature x three days, against which the client of course argued back.

Reasonably enough, I listened, and then naturally gave counter arguments, but still the client insisted “this feature will NOT take three days!”. Going back and forth I realized that the gap of understanding the feature between us was too great.
One way this could’ve continued is that I would have sat with him, tried to come up with all the possible scenarios and all the details involved in building feature x… until I convinced him, or of course until he convinced me. Weighing the costs and the benefits of this approach, it was not worth it! we would have wasted probably couple of hours just arguing if the feature is going to take 1 or 3 days; this means that we would have wasted between 17-50% of the feature time arguing how much it’s going to take!

So I chose not to go that direction, instead I questioned the value of estimating in this scenario, do we really need to estimate the details of this feature in a 10 days project? estimates are needed to take decisions now for situations that is going to happen in the future, the decision has to be made RIGHT NOW. So what is the decision we are trying to make here? The client’s answer was “I would build feature x differently”, so it was the “How”; how should we build feature x? should we take shortcuts? should we cut scope?
Of course we need this decision, but do we need it NOW? as we said it is so expensive; we are in dispute and remember it’s 17-50%!

How can we solve this? the answer “I don’t need this decision right now”, and hence I don’t need estimating it! but how did I come to this conclusion? How did I know that I don’t need it? by examining the rest of the features; if all the other features are so basic, of a higher importance, and on which there was no dispute,… then I can push feature x to the end of the project, and only when I start implementing it I would revisit my decision of how to do it. By that I will have had proper picture of how things are going and would be able to decide how to build it without the fear of messing up the whole project, and without delaying it by wasting time in estimating, “it is going to take what it is going to take”.

Let’s take an example.
In every morning I do four things:

1- wash my face
2- iron my shirt
3- pack my laptop
4- pack my lunch

I know exactly how long each of these tasks take, except for number 2; it depends on the fabric of the shirt, the performance of the iron…etc. Now, when I wake up I need to estimate how long these tasks take so I can “decide” whether to call my employer and inform him that I’d be late or not. In order to do that I would sit and think “hmm…how much time would ironing my shirt take me? if my blue shirt is already washed then it would be good because it’s the easiest to be ironed, but then the iron could need water, if I start filling it…” and I would spend god knows how long thinking of how much time ironing my shirt would take.
Instead of doing all that, I prioritize; I push task 2 till the very end and then when I am ACTUALLY DOING the task, things are much more clear and I can DECIDE if I can iron my blue shirt, or take a shortcut by grabbing my white t-shirt, and eventually to call my employer or not.

Maybe the following diagram would make the picture little bit more clear.

Picture3

You can see from diagram 1.0 that having the ambiguous task in the middle puts all the subsequent tasks into risk.

Picture4

Diagram 2.0 shows that pushing the ambiguous task to the end mitigates the risks, and leaves the decision of how to build it just before it starts with much clearer vision.

Conclusion

The highlight here is NOT about estimation, the highlight here is that every project is unique and should be assessed accordingly; before taking any step during the project ask yourself what value does it provide? what cost does it incur? is there other ways by which I can achieve my goal?

Happy delivering 🙂

Consultant Skills: Knowledge Depth & Breadth

It’s a crazy era for IT! everyday new concepts, libraries, products, and even languages are introduced; so many solutions for so many problems. It is indeed the era of specialization.

There is absolutely no way to grasp all this knowledge, specialization and concentration of knowledge has to occur, and we must choose a technology to specialize in. But… (You knew this was coming, didn’t you)… this is not good enough!
Before you jump on me and start yelling “But you just confessed; it’s impossible!”, let me explain.

Different roles require different type of knowledge, depending on what? depending on the problem the role is supposed to solve; some problems are so deep and complicated that requires specific field knowledge as deep and as complicated. The solution to the problem lies in deeper knowledge.

On the other hand, some problems require little bit broader knowledge, because the solution of the problem might not be buried too deep; it might be hanging there closer to the surface, but little bit further on a related knowledge.

And being the humans we are; weak, ignorant, and with short life span, we (as individuals) can either go deeper in specific field knowledge, or span wider in related fields knowledge, but rarely both.

The following diagram is my trial to draw this graphically:

KnowledgeGraph2

Let’s take Medical Science for example: Specialists and GPs (I really wanted to find a better example;  GPs these days have a bad reputation!).
The Specialists role should solve problems that require deeper knowledge of the field, e.g. eye specialist, his knowledge is higher on the y axis, shorter on the x axis, something like the Orange line.
On the other hand, the GP’s role is NOT to solve too specific problems, the GP is needed as a hub; he/she needs a breadth of knowledge that will enable him to direct the patient to the right source of the solution, so he should span more on the x axis and lower on the y axis (something like the Green line). I guess this also applies for Software Consultants, maybe.

But what does all this mean? it means that in order for you, my dear reader, to become a successful professional, you have to figure out how your diagram should look like. How to do that I hear you say?  three things you should be doing constantly to figure this out:

note:don’t try to draw the diagram per se, it’s only a metaphorical way to make the picture clearer in your mind

  1. Decide which field is the one you’d love to make your home? which field you’d want to spend most of your time growing in? When you find that, set it as your base, and then lay related fields in order according to relevance
  2. Think about your role, in general, what is the problem your role usually tries to solve? where in the diagram do the solutions usually lay?
  3. Update the diagram regularly; as time goes by, humanity advancement forces the axis’s to a zoom-like effect: we get deeper knowledge, and we have wider knowledge (as humanity), and so you have to know your capacity, and maintain a slope that covers the proper spans for your role.

And as you may have discovered, the ways used to acquire the knowledge varies depending on the depth or breadth of the knowledge.
Here are some, starting from deep knowledge to wide knowledge:

  1. Teaching
  2. Attending courses, detailed text books, and practice
  3. Videos and community sessions
  4. Articles and white papers
  5. Skimmed reading
  6. Reading titles only, and news on Twitter

Finally, striking a balance between the depth of knowledge and the breadth of knowledge is not an easy task, but let me end with a key tip: I have noticed that most of the successful Software Consultants I have interacted with have a really good breadth of knowledge, and then they bet on their ability to dig deeper when needed.

May your diagram be the highest and widest Smile.

On Building Quality Software

onion-chopsThe 2nd main cause of buggy software (time pressure is #1), is laziness and boredom.

Every job in this life consists of a “core”, which is the most challenging and most exciting part of the job, and a “chore”, which is the boring and tedious part.
Let’s take a chef as an example; he is an artist whose art is producing quality food, a process that involves mixing precisely-scaled ingredients, perfectly stirred on a period of time, or fried on the grill with an artistic movement…all are actions that the chef consider as crucial part (core) of the process producing the magnificent product of his.
On the other hand, the chef sometimes has to chop onion into xxx-small size of chops, a task that may be really boring to him (I wouldn’t blame him!). Being such a boring task, the chef is tempted to getaway with just xx-small size of chops; after all 95% of the meal preparation is there! So he ships the dish to the customer.
The customer tastes it, he generally likes it, but something is wrong…”ah!”, the customer discovers, “I am chewing pieces of onion!”. He almost rated the restaurant 4.5/5, but just that last bit ruined it!
3/5 is the final rate.

Ok maybe I dwelled a lot in that example, but to some extent this is exactly what is happening with the software developer. The task consists of exciting bits of code (core) that itself is the crucial part of the solution that solves the business problem; challenging, exciting, and fun to do.
On the other hand, the developer has to do some boring and tedious coding along (chore): arranging resources, validation, checking for nulls, breaking code into concise functions, cleaning up removable bits, or disposing resources.
All these tasks are not inherently part of the core solution, but if not done properly… if the developer thought he could just getaway with xx-small chops of onions, … if he does that the software might still generally work, but it will be buggy and less of quality, which will increase the chance of customers’ disappointment, or even abandoning it for good.

Finally, it is pretty safe to say that all the developers whom I thought were the best developers, they all did their chores ALL THE TIME, no excuses; all the tedious work mentioned above is done AND sufficient unit-tests is put to ensure it is done. Their joy of delivering bug-free software is higher than the joy of just solving the mind-stimulating core problem.

Don’t be lazy Winking smile

Don’t Just Fit Into The Gears

rusty-gears2Most of jobs in our modern world come with a job definition; a list of tasks that is expected from the candidate to accomplish during his/her occupation of that role. Very convenient approach; setting expectations for both parties.

A convenient approach indeed, but extremely dangerous as well! what is dangerous is NOT the job definition, rather the mentality it instills in the mind of the candidate.
The candidate examines the list of tasks, believes that he can do it, he takes the job, and once he starts in the new role he just fits into the gears of the existing environment/process, regardless of how rusty it is, or how inefficient the mechanics of these gears are! The environment or the process, part of which this role is, could be extremely malformed, inefficient, slow, or of any negative attribute you can stamp on a process that is not 100% fulfilling its goal. Just fitting into this system will make you part of this failure! But for innovators and positive influencers this is absolutely not acceptable.

If you examine any success story that happened within a process or an established environment, you will find that those who caused this success have actually revolted against that process at one point; they didn’t just accomplish “what expected” from them, they didn’t just accept the constraints as proven fact, on the contrary; they took one step back, went out of their specific “role”, analyzed, criticized, and then took a brave action to change. 

Fitting into gears can be expected, to a certain degree, in situations where a job description consists of “rigid tasks”, but it can still happen to roles whose job description consists of “introducing change” (e.g. consultancy). But how can this happen? by:

  1. Being overwhelmed by too many variables: a lot of things might be happening all at once in the environment we want to change, trying to solve all these at once will only result of waste of effort; it’s pretty simple and straightforward formula: x/y=z the bigger y is the less z is. And the solution is simple and straightforward too: focus on the highest priority, and traverse by time!
  2. Despair of change by rigid constraints: decision maker’s mentality, rigid environmental constraints, …etc. All of these can be solved by different ways depending on the nature of the constraint, but  “despair” is the keyword here; once the one reach that stage, he has a serious problem. Despair should not be reached before many trials of corrections acts, and in all different ways, but once it is reached, action should be taken immediately; it’s absolutely not allowed to stay in this situation unless it’s a consciously-made decision. Otherwise, scenarios of escalation, or dropping off, should be valid.
  3. Time lapse: this is the most important point because it is so subtle; what starts as a trial to accommodate to a new environment/process on the promise of change in the “near” future, evolves into an acceptance of the ugly environment/process simply because we “got used to it”.
    The best solution I’ve come across for this problem is talking to influencer people who change things to the better so often that you are constantly reminded that “change” and “making things better” is actually the real task to accomplish.
    If you can’t find such people around you, just print yourself a paper “What can I do to make it better?” and stick this to your monitor!

These three points are not the only ones, many things can also drive to the Fitting-into-gears scenario, though, I find these are the most common.

Of course this doesn’t mean to revolt always and on anything, sometimes something is just right and better left intact.

Conclusion

Don’t just fit into the gears, but step out, analyze, criticize, and change.