Technology have been a big part of my life ever since I was a kid. If it wasn’t a console it was a computer and later came the mobile phone. All these things running on electricity have always interested me. My first mobile phone was a Nokia 5110, which is the only phone that actually never broke.There’s a joke around the net that the old Nokia phones never broke and that’s very true; however they didn’t do much more than calls, sms and snake.
When the phones with color displays appeared the mobile vendors noticed that people wanted to switch phones often; as soon as a new feature was released everyone had to have it. The vendors immediately started pushing out more and more phones, a lot more phones than were actually needed on the market. With this overwhelming amount of mobile phones and rapid development came a lot of more bugs.
Since I swapped from my first Nokia phone, I haven’t had a single phone for more than 1 – 2 years. This isn’t because I really needed to get a new phone but because after a long period of time it started feeling slow, less responsive and lacked all the cool features the new phones had. If the consumers want to buy new phones every second year, why should the vendors make phones that work for more than 2 years?
This has gotten too far, I’m not talking about the mobile phones but technology in general; the consumers are expected to change their behavior and their hardware/software often (every 1-2 years). What’s scary about this is that I’ve caught myself saying:
Oh, you’ve got the 2 year old version/model. That program/accessory doesn’t work on that version/model. You need to upgrade.
As consumers have somewhat adapted to this and expect rapid updates for software’s. The vendors no longer need to spend as much time on finding bugs as they did before. A very good example of this is the launch of Diablo 3 where Blizzard needed to push Diablo 3 to the customers without it being completely finished. If you played Diablo 3 when it first arrived and play it today, it’s almost as you play 2 completely different games; the story the same, but other things have changed.
It is not rare that vendors have open-betas of their in-development software or hardware. In Office 2013, Microsoft added an “instant feedback button” and this is Great! However, I’ve seen a lot of software’s where they “forgot” to remove the “report a bug”-button in the RTM (release to manufacturing). Of course it should be easy to report a bug once you find it, but nowadays it’s pretty much like the vendors expect the users to find bugs and that they need rapid ways to report these.
We no longer see bugs as exceptions, but it’s rather expected and when we do find a bug we immediately think “this will be fixed in the next version sometime this week”.
Stop delivering less than awesome software
We’ve seen that consumers are not scared of changing their behavior, as that’s what we do; we adapt. Vendors need to start delivering better software and hardware!
As a software engineer, I know what I can do to ensure that each piece in the software that I create is high quality. If you don’t feel that you’ve done an awesome job, something is wrong; we need to be proud of the software that we deliver!
It’s quite often that bugs derive from “quick fixes”, but a quick fix can turn into a quickly evolving bug.
Here’s what I suggest we do to ensure quality of things we deliver:
Test, test and TEST!
Refactor your code according to the programming guidelines of the language your using
Write documentation (even if short!) about your methods, flow and functionality
Write test documents which includes both manual and automated tests
Create automated UI tests
Run complexity analysis tools such as NDepend on the code base to find too complex areas
Don’t deliver if you’re not happy with the outcome
Write readable code
Don’t try to optimize better than your compile can by writing complex and un-readable code
Drink a cup of coffee before you deploy
Let’s make better software, together!
What’s your suggestion on ensuring that we deliver high quality?
James Sugrue from DZone was able to get early access to C# Smorgasbord and has written an article about it. He also had the opportunity to do an interview with me.
I have gotten a lot of questions regarding the digital copy/ebook, I’m happy to share that the PDF, epub and mobi versions of the book are free if you purchase a printed copy!
If you’ve purchased C# Smorgasbord and are looking to retreive the digital copies, just fill out this form.
C# Smorgasbord covers a vast variety of different technologies, patterns and best practices that any C# developer should master.
Looking at everything from testing strategies to compilation as a service and how to do really advance things in runtime; you get a great sense of what you as a developer can do. By taking his personal views and his personal experience, Filip digs into each subject with a personal touch and by having real world problems at hand; we can look at how these problems could be tackled.
No matter if you are an experienced .NET developer, or a beginner, you will most certainly find a lot of interesting things in this book. The book covers important patterns and technologies that any developer would benefit from mastering.
Explore your possibilities Improve your skills Be Inspired to challenge yourself
Since the fall 2011 I have been working on a book called C# Smorgasbord. The book is inspired by all the interesting topics that I’ve touched in this blog.
I’m proud to announce that the book will soon be available for purchase on Amazon and CreateSpace! You will also be able to purchase digital copies on the website for C# Smorgasbord.
It will be available for purchase August, 2012.
The cover
The cover is produced by a very talented art directory, Christoffer Saltelid and looks like this:
3D-view of the book
A little bit about the book
Looking at everything from testing strategies to compilation as a service and how to do really advanced things in runtime; you get a great sense of what you as a developer can do. By taking his personal views and his personal experience, Filip digs into each subject with a personal touch and by having real world problems at hand, we can look at how these problems could be tackled.
No matter if you are an experienced .NET developer, or a beginner, you will most certainly find a lot of interesting things in this book. The book covers important patterns and technologies that any developer would benefit from mastering.
Table of Contents
This is the top-level Table of Contents for C# Smorgasbord:
Introduction to Parallel Extensions
Productivity and Quality with Unit Testing
Is upgrading your code a productive step?
Creating a challenge out of the trivial tasks
Asynchronous programming with async and await
Dynamic programming
Increase readability with anonymous types and methods
Exploring Reflection
Creating things at runtime
Introducing Roslyn
Adapting to Inversion of Control
Are you Mocking me?
If you head over to books.filipekberg.se you can pre-order a digital copy today.
It is truly a great pleasure to finally be able to spread the word about NDepend version 4. For those of you that do not know what NDepend is, you have truly missed out on something great. But not to worry, you can catch up in an instant!
NDepend is a complexity analysis tool that integrates into Visual Studio 2011, 2010 and 2008. It also comes with a standalone component for analyzing your projects.
I have been using NDepend v4 for a while now and I liked it so much that it gets a place in my upcoming book.
What makes NDepend so powerful is that you can customize the analysis to adapt to your own set of restrictions and you do this with what is called Code Query LINQ(CQLinq). This is one of the biggest changes in version 4 and it really takes the tool to another level, prior to version 4 you used another way to customize your queries.
from m in Application.Methods where m.CyclomaticComplexity>15&& m.PercentageComment<10 selectnew{ m, m.CyclomaticComplexity, m.PercentageComment}
I made an analyze of the ASP.NET Web Stack project and this is what the report look like in the stand alone program called Visual NDepend:
In the image above it shows the dependency graph you have a lot of other views that you can use to find complexity in your solution. You can also see a list of the different CQLinq results such as:
Types that are too big
Methods that are too complex
Methods that takes too many parameters
When composing this analysis you also get an HTML Report that looks like this:
It essentially contains the same information as you would get from Visual NDepend, but it is very handy to be able to pass this report on to fellow co-workers.
Another Very powerful thing is that you can integrate NDepend with for instance CruiseControl.NET, which is a build server. This means that every time the build server builds your project, it can also analyze the solution and compare how your complexity increases or decreases.
You can get a 14 day trial, I really suggest you do, you do not want to miss out on this! There will also be much more content regarding NDepend in the book I am currently writing, stay tuned for more information about that.
Happy 2012 folks! I hope you all had a wonderful new years eve!
The year 2011 has been very interesting, we’ve had the opportunity to see some very exciting things that is about to reach the market. I’d like to summarize what I’ve been writing about in 2011 and breifly tell you guys what’s about to expect from me in 2012.
Let’s get to it, here’s a link summary to all my posts in 2011
As you can see a lot of exciting things has been discussed in 2011 and my vision is that 2012 gets at least as exciting! We’ve still got a lot of fun areas to cover and even more useful products to look at.
Worth mentioning is that I am currently in the work of assembling a book about C# Programming, almost all the above articles and some more will be featured in this book but with a lot of extra content that makes it even more fun to read. If you are interested in being a technical reviewer, editor or anything else that might be helpfull, just drop me an email or a dm.
You might have come across the phrases IoC, Dependency Injection, Mocking among others, these are commonly used when talking about “Inversion Of Control” which is the full meaning of the abbreviation IoC. So what is this “IoC” that everyone is talking about?
Inversion of control is a principle in Software Engineering, let’s just take a look at the Wikipedia definition of this
In practice, Inversion of Control is a style of software construction where reusable generic code controls the execution of problem-specific code. It carries the strong connotation that the reusable code and the problem-specific code are developed independently, which often results in a single integrated application.
Rather than explaining the text below, let me show an example of an application that does not follow this principle, but will when we’re done here! I’ve got a solution prepared that looks like this:
This solution simulates an order process, where we’ve got a window where we can place some kind of order and then we’ve got some sort of payment provider that executes the order request. This is the only content so far in the InversionOfControl.Payment library:
All we’re doing is to check if the data we send into the execute method actually contains any information at all, if it doesn’t we return a failure result, otherwise we return a success result. Keep in mind that when you implement communication with real payment providers, there are a lot more code to it. But let’s keep the example clean!
The order form is very simple and looks like this:
When we press the button this is what’s going to happen:
publicvoid ProcessPayment(string orderData) {
var paymentProvider =new PayPalPaymentProvider();
var result = paymentProvider.Execute(orderData);
MessageBox.Show(result.ToString()); }
So far we’ve got our order form where we can place an order, when we place the order we execute our order placement and directly communicate with our payment provider. Let’s call this Step 1, we’ve set up the project and we can execute a payment, you can download the code here, unzip it and look in the folder named Step 1. You can also browse the code on github.
Let’s bring up another one of those commonly used abbreviations; TDD or Test After Development. Payments are a great example of something that really needs to be tested thoroughly and you can’t have any errors here. Because either it will be expensive for you, your customer or the end user, no matter which one, you’ve got a big problem.
But what happens when we introduce testing at this stage? How do we actually test the entire flow of the application without communicating directly with payment provider? This is where Inversion of Control and Dependency Injection comes into play. Dependency Injection is a design pattern with the following Wikipedia explanation
DI whose purpose is to improve testability of, and simplify deployment of components in large software systems.
The pattern involves some rules that we need to adapt to, which basically means we have to write cleaner and more testable code. In order to make our code cleaner and more testable we need to break some of the static parts out, this being the actual instantiation of a concrete type in the payment processing.
There’s something “wrong” with it; We’re instantiation the concrete type here! To make the method testable, we don’t want that because this means that it will always use our real payment provider information and execute the order against it, which can make the testing expensive for the tester ( if he has to provide is credit card number all the time that is! ).
The easiest way to break it out is to move this to the method argument list, which means that instead of creating an instance in the method, we want someone else to inject it to us. Let’s look at this in a two-step refactoring, first we move the declaration outside of the context and change the method signature:
publicvoid ProcessPayment(string orderData, PayPalPaymentProvider paymentProvider) {
var result = paymentProvider.Execute(orderData);
MessageBox.Show(result.ToString()); }
This will let us create an instance of PayPalPaymentProvider before we call the processing method and inject it when we call the method. But we are still working with the concrete type, so let’s take a look at the next step in the two-way refactor, let’s simply it to an interface!
All the interface need to tell us is that we’ve got a method called Execute that will return a result to us, so we simply declare it like this:
By the looks of it, we now have a simple and elegant way to process our payments, let’s create a test project and reference to InversionOfControl.Demo. Now create a test called PaymentTests.
So how do we start testing the payment processing?
We only have one concrete payment provider at the moment and this one we don’t want to use for our unit testing, so what we will do instead is that we will create a fake class that will act as the real payment provider, this is dependency injection! So in our payment project, add a new class called FakePaymentProvider and just have it look somewhat like this:
Now the test itself isn’t that hard, we’ve already covered the hardest part and that was doing the actual refactoring. So, this is what my test ended up looking like:
I’m initializing my test by creating a fake payment provider and then I am testing if it fails and succeeds as I expect it to, we’ve got a nice way to test our code! This brings us to the next problem, where Dependency Injection and Inversion of Control meet each other, what if I want to test the flow of my application, without actually changing the concrete instantiations everywhere to FakePaymentProvider?
This is where we’re going to bring in a library to help us along the way, but before we do that, let’s just talk a little bit about what is going to happen.
So we’ve got a system that is now refactored so that the important methods that we want to make testable no longer use the concrete types as parameters but rather interfaces that we can implement to create our fake repositories or providers of some sort. The next thing we want to remove completely is the way that we create an instance of our concrete type before we invoke the payment provider.
To do this, we’re going to use a library that let’s us define what kind of implementation to use in runtime. To do this, I’m going to take some help of NuGet to install a library called Ninject. Ninject is an open source dependency injector for .NET and it’s Very good!
Fire up NuGet and let’s start installing those packages!
All you need to write is the following:
PM> Install-Package Ninject
Be sure that you’ve got “InversionOfControl.Demo” selected as “Default project” and you should see something like this:
There are a lot of different type of dependency injectors out there and they act a little bit different. Ninject works like this: you tell ninject what types you want bound to what types or interfaces and then you request these types. There are other dependency injectors that will just replace all interfaces with the concrete type of your choice, but I like Ninject because it gives us an extra type of abstractness and there’s not that much magic to it.
Basically we need to know two things in order to get started with Ninject ( There’s a great Wiki if you want to know more ) first of all, you use something called “Modules” to easily define different types of bindings. For instance, we’re going to create a module that is called PaymentProviderModule. The second thing is that you use something called a kernel to retrieve the concrete types and you tell the kernel which module it should use.
All we’re saying here is that each time we ask for an IPaymentProvider we’re going to get a Fake payment provider. Now let’s take a look at how this changes the rest of the code! Let’s head over to the order button event handler. The only thing that actually changes now is how we retrieve a concrete type of IPaymentProvider and this is how we do that with Ninject:
Notice this part in particular kernel.Get<IPaymentProvider>(), we’re actually requesting the interface and not a concrete type! Let’s run the application and see what happens, if we enter anything else than “OK”, we should see a message box that says “Failure”:
And it does!
We’ve successfully made our application less dependent on the concrete type and we’ve introduced testability which we had no way of doing before! The example code for the payment provider is as stated before a bit thin, but in a real world scenario the fake payment provider might not be much bigger than the one we’ve got here, but the real concrete type might.
Now let’s take a look at that definition of Inversion of Control again; it basically means that our application should be able to execute anything against any payment provider without ever having to know about its implementation! We’ve only scratched the surface on how this helps out with testability, there are great frameworks that will help us even more without having to actually create a new concrete type for testing, which in this case was our fake payment provider.
As you might see this is very powerful and gives us a great way to make our applications more testable which will make them more reliable. You can look at the code at the github repository. You can also download the code here.
I hope you found this interesting, if you have any thoughts please leave a comment below!
It’s been almost six months since my last blog post here, it’s not like I don’t have anything to write, but the time I have over at the end of the day just doesn’t end up so that I have time to write here. I’ll try to get some more time to write here since I really do have a lot of interesting things that I want to share!
Lately I’ve seen a bunch of questions over at StackOverflow that is quite trivial, at least trivial to us that work with these kinds of things on a day to day basis. My example here is from the question “how to read all the subdirectories in a given destination..” as I see it, there are a lot of different ways that you can solve this but no matter how trivial this problem is, you can always over-engineer it. So when I first saw this question I immediately started to think about interesting ways to solve this.
One of the possible solutions could be to get a directory list of the parent folder and use parallel extensions to recursively scan each folder to speed up the process a bit. The traversing method signature could also contain an action / delegate that are used when the given file you are looking for is found.
However, this does not completely solve the given task, the person asking the question wants the following requirements:
Start looking for the ABC file in the parent directory
If there is no ABC file, go on to the next subfolder
If it is not in the subfolder, move on to the next one…. and so forth..
Once a file is found, process the file
It is however not stated if the scanning should continue after the first file is found. Do you see where I am getting at? When you open to door to allow different interpretations of your problem, a lot of us that see interesting challenges in everything start to think about how we can effectively make this reusable and optimized.
Over-engineering a trivial problem can actually lead to something good, you might get optimized and reusable code!
One of the solutions presented was actually pretty cool, there’s something called “LINQ to File System” which will let you create a query and ask for these files, and you can use the built in System.IO.DirectoryInfo directly to ask for a certain file-pattern. But neither of these lets you process the file In-Place. What I mean about In-Place is to process it once you’ve found it and not after you’ve found it.
My final solution ended up being a recursive method that just takes a path; this was to give the trivial question a trivial answer.
void TraverseDirectory(string directory) {
var currentDirectory =new DirectoryInfo(directory);
foreach(var dir in currentDirectory.GetDirectories()) {
var currentPath = dir.FullName;
TraverseDirectory(currentPath);
var pathToMasterFile = Path.Combine(currentPath, "Master");
Even though this problem was initially trivial, if we want to, we can make it very complex, challenging and educating. For instance, it’s been a while since I created something interesting with Delegates/Actions/Tasks so why not elaborate this a bit and make the result a bit more interesting?
You can always make trivial problems into something fun, exiting, educating and challenging! You just need to put your mind into it. Mainly I just want to say to all developers out there that are stuck with trivial tasks that they find a bit boring; you can make so much more out if it!
This is by far the most asked question I’ve seen around the net besides the obvious questions like “How do you do X and why doesn’t Y work?”. There is a simple answer: If the code works and is patchable, we don’t need to rewrite.
I’ve heard that line countless of times from both customers and PM:s when arguing about rewriting old systems and to be fair, it’s not an invalid statement. Why should be re-build something when it is properly working? In my opinion there are a couple of reasons why you would need to consider rewriting code that is working.
The old framework has security issues that will just take to much time manage and there will be to many “fast fixes” in the code so that in the near future, it will be hard to handle.
It’s hard to implement new features and integrate with new systems that the customer requests.
There are too many new developers on the team that do not have knowledge regarding the older framework and it will therefore be beneficial to rewrite.
One might argue that some of the above will count as “the software does not work” since it’s not manageable anymore. And to be honst, to old code is hard to manage and costs more than it needs to. For instance, Microsoft recently said that they will stop supporting VB6, hello? It’s 2010 and we still develop VB6 applications and manage old VB6 applications.
I am not trying to say that the VB6 code that was written is bad or that it will be cheaper right Now to rewrite but in the end I think it could somehow benefit both the developers and the customers. Visual Basic first appeared 1991 and version 6 which has been the latest Visual Basic version outside the .NET family was released as a stable release 1998. That’s 12 years ago, how much really happens in 12 years?
12 years ago I got my first computer which had a Pentium 2 CPU with 350Mhz and less than 128MB RAM doesn’t that say just a little bit how far we’ve come since 12 years ago? Today you can get a 6 core CPU with over 4Ghz and a lot of gigabytes of RAM.
Put that in the context of programming, it’s been 12 years of security fixes, system updates, patches on developed systems and the biggest change of all: A bunch of new Operating System updates with a couple of major releases. Well I am not here to bash down on VB6 but to reflect a bit on if it is really worth upgrading to a newer framework.
What if you have a system written in .NET 2.0 with C# using ASP.NET ( WebForms ) will it be worth the effort and money to upgrade/convert this system into .NET 4.0 with MVC 3? I’d sayd: It depends!
First of all you need to think about how it will benefit the customer. If you have a comittment to the customer and handle all upgrades and new development, maybe you will get a lot more features for a much less cost if you use a much newer framework, because in a new framework you get a lot of help solving trivial problems.
So in a longer term you might actually help the customer reduce the administration cost, but the up-front cost might be a bit higher to just get you and your team over the cliff to a finished upgrade.
The answer to this is quite subjective and I still think that it depends a lot on the project and that you need to think about how it will benefit the customer or the development team. A while back I answered a question on StackOverflow about the current topic, the poster wanted to know if it was a productive step to rewrite from Language A to Language B and my answer was:
You need to take some parts into mind here,
What will you gain from re-writing
Is it an economically wise decision
Will the code be easier to handle for new programmers
Performance-wise, will this be a good option?
These four points is something that is important, will the work be more efficient after you re-write the code? Probably. But will it be worth the cost of re-development? One important step to follow, if you decide to re-write, make 3 documents, first Analyze the project, what needs to be done? How should everything work? Then put up a document with Requirements, what specificly do we need and how should this be done? Last but not least, the design document, where you put all your final class diagrams, the system operations and how the design and flow of the page should work. This will help a new developer, and old ones, to actually think about “do we really need to re-write?”.
Function pointers? you might ask yourself, well this little trick gets handy sometimes, I will provide an example of a practical use in a later post on the next euler solution. Might actually do it in C too just to prove that C is still neat.
So to kick this off, what are function pointers? Well for those deep down the rabbit hole ( .NET guys that is ), might not really have a clue on the matter, and others might dissaggree and now exactly what it is. So just to keep the air clear here, function pointers are “pointers” that direct you to a function, easy huh?
Well, you probably got as much from just reading the phrase but, it’s not really rocket science. If you are familiar with references or reference types, such as Strings and Objects, you know that there are different types of memory in which your program operates. When you create an Object you store your data on a shared memory place. There are shared memory and program reserved memory ( the stack! ). So you might want to look at this as a “reference” to a function.
So when would this be nessecary? Imagine the scenario where you might want to performe some calculation but you don’t know what type of API the end user which will end up using your API have. Let’s say that the method “square” ( x^x ) would not be defined. So you might end up having to use function pointers, where you ask the user to suppy the function for calculating square of x.
In Python the Square function for x^x will look like this
def square(i):
result = i; for x inrange(i-1):
result *= i
return result
In C it will look like this
int square(int i) { int result = i; int x =1;
for( x =1; x < i; x++) {
result *= i; }
return result; }
Now these two look fairly similar don’t they? Well sure, the only real difference is the dialekt right? It’s just programming. So let’s get to the cool parts. In python, we would solve this problem easy, since it’s not a strongly typed language everything could be a function, right. So let’s check the decleration for calculate.
But before we check that out, let’s just make it clear that our Usage will be somewhat like, give me a function that calculates square of a+b, this means, the result should be (a+b)^(a+b).
So this is the function decleration in Python
def calculate(func, a, b)
Not that hard, right? Well, keep in mind that Python is a “modern” language, it’s more of a scripting language.
Check this out and notice the fairly big difference
int calculate(int(*func)(int c),int a,int b)
If you are not familiar with pointers I would suggest you dig down the archive on my blog and check out the chapters about that. So what this really does in C is that you tell the compiler that, okay this function takes a pointer to something that will look like this, and you write the declaration of the function again. So, in this case you really need to know what it looks like. With standard parameter values in Python you could acheive some really cool things without knowing the decleration of the function.
Now we’ve seen how to Create the methods, taking arguments that are functions, how about using them inside your code?
Check this C example of the whole Calculate function
int calculate(int(*func)(int c),int a,int b) { return(*func)(a+b); }
And in Python the following will look like this
def calculate(func, a, b): return func(a+b);
There is a notable difference here, but I can honestly say that I like the C-style.
Try out the python version!
#!/usr/bin/python
def square(i):
result = i; for x inrange(i-1):
result *= i
Often when developing software such as websites, windows ( or any other operative system for that matter ) programs, the begining of the progress is quite simple; you have your ideas and may have some thoughts about how to implement everything. But what often is forgot when developing software is the importance of thinking ahead, thus, planning for a larger software that you have in mind.
For an example, when i started developing SmartIT Invoice i thought of it as a software that would generally help me organize my small amount of invoices. But as the years pass my company grows bigger and bigger and once im up to n-numbers of invoices, a simple List View won’t be sufficient. Therefore after implementing my Invoice software, i started thinking about how i could change everything and structure the code for helping me in the future. I had in mind that i might not always want to use the Windows Graphical Interface for input and output so as i always do, i seperate the Design code from the Logical Code. This meaning that my application has three layers. Them being:
Application Layer, code for display, handling window events
Logic data layer, database connections, objects
Data layer, this being the database with functions, views and procedures
By having these three layers i can easily change one of the layers without changing the next. Of course this is not entierly true, i would have to change some parts in the Logic Data Layer if i changed the DBMS. I would however not have to change that much if i just changed the behaviour of a Stored procedure.
Again takng my Invoice softwre as an example, i recently released a software called Webexpress.nu which allows customers to create their own website and for this i need somewhat of a payment system. Of course using Credit card payments is nice and easy but not entierly nessesary. So by just adapting my Webste to the current Logic Data Layer of my SmartIT Invoice software, i could easily get an intergration that allowed me to create customer invoices that pops up on the user account, when they are online on the page of course and even directly to my software, withouth any adjustments in the Data Layer or in my Windows Software.
This proves the point that well structured code and seperate layers will help you along the way of program development.
As a side note the Data Layer in this case is a Windows DLL with .NET 3.5 code which makes it even easier to implement when the website itself is asp.net with .net 3.5.
There are a lot of good design guidelines out there which will help you structure your software better and help you understand how to always follow a pattern. A pattern doesn’t, in my point of view, have to be a pattern like Singelton etc, it can by any means be a way for yourself to regocnize your own code, thus following a pattern. Example, i often tend to use m_ before member variables and write all functions and access methods with a capital letter.
Filip Ekberg is a Senior Software Engineer working in the country with all the polar bears, author of a self-published C# programming book and overall in love with programming.
Check out my recently published book.C# Smorgasbord covers a vast variety of different technologies, patterns and best practices that any C# developer should master.
All printed copies include access to the e-book bundle (PDF, ePub and Mobi!).