Quality of Kentico CMS source code

   —   
Hi there! I found a moment in my busy schedule to post one more article. This one will give you an overview on what you can expect from our code and also reasons why you may want to buy our Source code license. If you are interested, read further ...
Our customers often ask about quality of our code and what they can get if they buy the source code license. Obviously, you cannot get the whole source code to see before you buy the licence and you are entitled to it. For that reason I want you to give a little sneak-peak of segments of our code so you can decide better.

A little of boring history facts ...

As always, I will be completely honest with you so I must start with something about previous versions. If you already know our code from previous version, so you may compare.
  • Version 1.x - When our company started 4 years ago, it was a company of one man. As you may expect, there had to be something which was wrong. Because when you start a business, you cannot just say "this is going to be great" without having the exact idea of what will happen in future. The bad thing about version 1 was the architecture. It just wasn't scalable enough and as the company grew, some of the parts were written by the external developers, which became problematic by means of not enough control over their work. They were under contracts for specific modules and it was very hard to give them their work back and meet the deadlines in time. I personally joined the company at the time of version 1.7 where it slowly became obvious that it cannot go that way for a long time. This is the problem of every virtual company and also free open source solutions build by standalone programmers, even if you have detailed rules, you cannot just control everything. One day, it just becomes too chaotic that it cannot be controlled. So honestly, I'd like to give you one advice here to help you avoid sleepless nights: Do not use free open source solutions or products of virtual companies in the projects, which you want to be good, because it can be a nightmare for you! One way or another, we had to deal with these things for some time, until we decided that this must be changed in order to make our product good enough for you, our customers, and it was the exact time to move to version 2 leaving all bad code behind.
  • Version 2.x - New version 2 had completely revised architecture, making the solution more scalable and friendly for the end users. What I like about it most and consider groudbreaking was the code. At that time we became quite recognized by the market, we could afford to split our employees into specific departments and become the company with new great office where everybody had his place and where we didn't need any external programmers anymore. The result was obvious, we had much more control of our code, and we were able to react to the problems in a real time, solving most of them at the moment they raised. This significantly improved our code experience, making it worth it for professionals like you. If I should give the code 1 to 10 where 10 is best, I would probably give 4 to version 1.x and 7 to version 2.x. Why 7? Why not more? Well ... at that time I would give more, but as we become more experienced, we also become more ambitious and of course we are still improving it, that's why. So the version 2.x had nice architecture, pretty nice coding, where is the catch? Actually, nowhere, with version 2.x our product became so nice, that so far no next version needed significant revision of the whole solution. See how great deal can bring you when you change from virtual company to an organized office? OK, so why next numbers?
  • Version 3.x - As I mentioned, version could easily continue with existing architecture so the numbering wasn't really the most important thing. You are right, the numbering is more about marketing and pricing. At certain points, we bring so many new or significant features to our solution that we must change the licensing or we just thing it is better for you to have clearly staged experience about versioning. 3.1 is better than stick with 2.83 or so, right? Also from your point of view, you are already getting a third generation of the product, which is obviously better than the first or the second. With new version, there usually also comes the time for management to meet and discuss the processes, optimize the working process and other things so it also gives you the idea on how we are getting better in what we do. From the coding perspective, the version 3.x is being optimized for performance (effective code) and as there is more and more developers in our company, the coding rules are getting more precise and better. I would give 9 points to our current version just for the reason that there is some code left which wasn't revised enough, but we are working on it, believe me.
  • Next versions - Of course my goal as the CTO is to believe that our code has 10 points from 10, we are working on it very hard, revising the modules one after another. It takes some time because in the meantime we of course implement new features which also must be revised, but the progress is good and we are getting close to finish it.
Would I use Kentico CMS for my project?

Well, that's the question ... I know all the code and modules of our system and I am also sort of perfectionist so I am very strict to every part of the solution I would possibly want to use, most of you would probably have lower requirements.

I would certainly use the version 1.0 to 1.8 to a smaller project, mostly because of its pricing at that time. I wouldn't however use it for larger projects. I would probably use version 1.9 for larger web sites, again, because the pricing was cool. But choosing the product just for the reason of price isn't the right thing, right?

Version 2.x was kind of cool from the start, having only some difficulties with the performance. I would use it for a smaller to medium project because the advantages of it were great for such price and it had really nice features. I wouldn't choose it for large project only for performance reasons if I wouldn't have my own servers or web farm.

I would definitely choose version 3.x, mainly 3.1a for my project of any standard size, because it kept all the great features and also solved the performance issues from previous versions, so my final answer is YES! it is great product for a decent price and it gets better every day.

Let's get to the point! ... Current quality of the code

First something about how our code is structured:
  • Libraries - We carefully divide the classes into libraries which may seem just too complicated to you, but on the other hand, gives you the reason why you should believe that the architecture is great. Every library has its purpose, grouping together the functionality of certain features or module. Every library also has its own namespace so that is clear where the classes belong. Our namespaces and library names always begin with "CMS." e.g. CMS.SiteProvider.dll and CMS.SiteProvider.
  • Classes - The classes are divided into several types, there are:
    • Info classes - e.g. UserInfo, which are API containers for the database records, encapsulating the data to the object.
    • Info providers - Managing code for the Info class data is stored in the provider class, which handles all the basic operations with the objects
    • Helpers or Utility classes - Helper classes usually provide grouped operations or general methods for data transformation or preparation. There is also one helper library GlobalHelper useful for the general operations not exactly connected to our CMS.
    • Other classes - Special cases require special classes, which cannot be just categorized.
    • Enumerations - For better programmer experience, there are of course enumerations in the cases user can choose only from certain values.
    • Constants - Important values are provided by the constants.
  • Controls - There are several libraries of server controls, structured by their purpose and need of references to other libraries.
  • Pages - Pages are carefully structured by their purpose, which gets even better with new version, directing to separable modules. Reused parts of the pages are implemented by the user controls so the code does not repeat too much.
  • References - There are always only references to the libraries which are absolutely necessary for the library. This gets even better in upcoming version where we are clarifying what depends on what.
You can see this is a pretty standard way how the project is structured, we carefully maintain the structure and everything must be approved. Now something about the code itself:
  • Namespaces - As I mentioned before, all our library code is strictly divided into namespaces starting with "CMS."
  • Standalone class files - Every class has its own file in the solution structure, somewhere we use folders for better orientation. Only some enumerations or delegates are included into common files to keep the number of the files low.
  • Naming conventions - Everything has its naming conventions: All our libraries, namespaces, classes, names, property and local variables, constants, method parameters, methods, CSS classes, resource strings, file names, icon names, enumerations, control IDs etc.
  • Code constructions - We always use brackets in conditions even when there is just one command, it helps avoiding the mistakes when you update the code. We also use brackets in all conditions to clearly specify the priority of operations.
  • Comments - Every public member and also non-obvious non-private member is properly commented. Also the processing code is heavily commented explaining the process. There are also internal rules on how to write comments.
  • Regions - Most of the code uses regions to separate the members by their type for better orientation.
  • Warnings - All our libraries are compiled with warning level 4 without warnings and signed with strong names, you get the key for signature with the source code license.
  • Data access - All data access from our code is done through our data layer, which is strictly required, otherwise you wouldn't be able to use you own data providers, right?
  • HTML and Javascript - We have our internal guides what to look for in HTML and Javascript and our development (and QA) team always tests the solution on all supported browsers.
  • CSS and design - Of course we have some rules for the design and CSS.
You can see that we have a lot of rules how to write our code, all this has two main reasons, first is to provide you the experience that the code "IS WRITTEN BY SINGLE PROGRAMMER" and "IF YOU UNDERSTAND ONE LIBRARY, YOU UNDERSTAND THEM ALL". This is basically our main goal.

Just to not forget to mention anything, I should mention that we use Team Foundation Server as our Source Control provider, just so you can see that the code isn't populated randomly and the process is organized. We used Visual Source Safe but as our project grew, it became just too slow for us.

Our typical process of development is following:
  • The developer creates the class / page / control following the Design pattern. Yes, the design patterns are important part of our solution and if you are creating some larger project, I recommend you to at least read about how it works, you will like it.
  • Then he implements everything which is on the top of the design pattern, which is special.
  • He reviews his code and functionality of it, and corrects what doesn't match the rules
  • The technical leader reviews his work and code, ensuring everything is correct and the module is working properly and efficiently. 
  • The CTO (me) reviews the module to see if it matches the requirements and can be delivered to the end customer.
  • QA department takes care about detailed testing of the features, performs the predefined test suites of every module, returning back anything that is wrong.
You can see both code and functionality is checked multiple times, to ensure proper effectiveness and functionality. Again, this is something you can never expect from a disorganized, open source community, the great deal of commercial product.

Do you want to see some code?

Of course you do, who wouldn't? :-) I'll just post here one of our very simple provider and info code, basically, this is the concept every provider uses this one is done clearly by our design patterns, with no special methods. It is just for you to decide how organized the code is.

MessageInfo.zip

You can see the code of user interface by installing the trial or free version, so I do not post here any of these. See for yourself.

What you get if you buy the Source code version and what you get if you buy standard version?

With standard version, regardless of whether it is trial or free, you get all the code of administration interface, that's basically the web project which is installed on your machine. You also get the full documentation and code samples. We want to give you as much information as we can, it is always better. With this standard version, you need to keep our DLLs and cannot change the default behavior of our Application and Data layers ... well that's not completely true, you can, but only through placed where we introduce the ability for customization, you can find the details on customization in our Developer's guide.


On the other hand, if you buy source code license, it gives you many advantages:
 
  • You can create hotfixes and change the default behavior of the providers by yourself so you don't need to wait for a new version to come out.
  • You can add your own, additional functionality to the providers.
  • You can let your experts analyze the code to be sure it really satisfies all your security requirements.
  • You can compile the project against any 3rd party components or make it compatible with it without waiting for new version.
  • You can get better understanding of the processes behind the UI and get more effective in what you do.
  • You can debug the code in our libraries to see why your code isn't working, what you forgot.
  • The source code version is fully functional project so you may run and install the database directly from the package of the source code you get from us.
And of course, you get the source code with each version until your subscription is valid, so you can directly compare what is new in the code in the new version in most advanced details.

For the experienced users and the partners who deliver sites to their customers on a regular basis, I recommend the source code version even if you do not exactly need it for your customers, because knowing exactly what is behind the API and being able to fully debug the application gives you an advantage over your competitors and solve your problems in a much more efficient way.


Upgrades ... be prepared for the future

I think the only remainig thing is to tell you how the upgrades to new versions work, if you have already made one, you already know. Still, keep reading, especially if you had to migrate from 1.9 to 2.x or 3.x, because I will explain why this is the past and that the future is bright.
 

You may be little confused by the picture, let's explain it, starting from the beginning. At first, there was the version 1.x and you used small upgrade packages to upgrade your project. The upgrade package (orange arrow on the left) is a simple zip file containing SQL database script and new / updated files of the user interface, also with all the new DLLs. The upgrade procedure works the way that you follow the instructions and usually run the SQL script over your database and replace the files in your project. It is very simple and we leave it to you rather than to some automated process to be sure you will take care about your backup and you can see what is actually going on. The process of upgrade with package takes from few minutes to about half an hour tops, including the backup of your project, depending on the complexity and how you upgrade. If you made some changes to the files which are new, you must take care that you do the changes in those, there is no automation process which could handle those.

This was working well until version 2.0 came out. The change of architecture broke the compatibility between 1.x and 2.x version but it had to be done, so the standard upgrade process had to be replaced by something else. Unfortunately for some of you, only half of the work was done automatically, by the aplication Migration toolkit which transformed the data to the new database (purple arrows on the right). The pain of the other half was that the developers had to convert parts of their code manually (the big red arrow) which is the thing no one wants to do, right?

When you are already at the version 2.0 and higher, on the V2 architecture, you can be happy, because it was carefully designed to be future-proof and since then, the compatibility stays with the solution. All the upgrades are done by the small upgrade packages, even to major versions, without any significant changes required to your code. You can expect the same for the next versions, we do not have any unwanted surprises for you so the upgrade process will stay smooth and fast for you.

Is this good or bad? Definitely GOOD for you! Because the worst thing you can ever do to your product is to stick with bad version of it. Yes, we made a mistake in the past, but we have learned from it which brought you a product which you can choose just for its great architecture and features. That is what is valued.

How about source code updates?

Source code updates are little bit more complicated. Since every customer does the changes by himself, we are not able to provide you with the tool that could handle it. If you change something, you should keep track of that to be able to change it in the new version. You can keep a list of changes, mark them with comments or use some comparisson tool to compare your changes against the original version. If you want to compare your changes, I recommend you the great tool Beyond Compare. Of course you need to recompile your solution and run the SQL upgrade to your database in that case.

Enough, let's have some rest

Thank you for staying with my maybe too long post, I will get back to you as soon as possible, because I already owe you the September summary. See you later ...

M.H.
Share this article on   LinkedIn Google+

Martin Hejtmanek

Hi, I am the CTO of Kentico and I will be constantly providing you the information about current development process and other interesting technical things you might want to know about Kentico.

Comments

Martin Hejtmanek commented on

Hi Mehrdad,

You need to buy the Source code licence to get the full source code. See http://www.kentico.com/Buy.aspx for details on pricing. With standard licences (including the free licence), you get only the source code of the admin UI, which is still great deal in comparison to other products.

Mehrdad abdi commented on

Hi,

I just downloaded the free version of this product (Kentico)

but could not find source code for data access for example AbstractInfoProvider

do we get thsese source codes?

Martin Hejtmanek commented on

Well, the only thing I can suggest here is to go first to the Developers Guide and read the chapter API Programming and Kentico CMS Internals, that would certainly help you to get some first directions. Definitely better than just dive into the API reference. For anything around editing of the documents, check the DocumentHelper (CMS.WorkflowEngine) first, that's the top layer on top of the documents. Or maybe just find the right providers (classes) by searching the object name in the API reference (if you search what's in the title of admin interface, you quickly get to the right location), do not start by searching the assembly.

Kentico CMS is quite a large platform, so there really have to be that many assemblies and namespaces. And I have one more question to think about ... If you look at .NET itself, I don't think you started by looking at the list of assemblies when you started with it, have you? You probably went through some tutorials, found some examples and started to be oriented in just few of them and as your projects continued, you learned more and more. You have to do the same with any solution. Everybody has a different perception of what is good and what is not so good, so there is really no way how to make the namespaces "nice" for everyone, that's why we have them defined by the modules, so there is at least some order in them.

I agree that using where conditions may be complicated in cases like getting the documents in a category, but the tags and category stuff is quite new so we are still working on that to make it comfortable for everyone. And as I said, until we are on .NET 2.0, we cannot offer LINQ, but you are free to use it.

random0xff commented on

"BTW, can you tell me what you thought was confusing about our API?"

Many things... The namespaces are _really_ confusing, I can't find anything!

Working with attachments is very inefficient. It seems like a game of collecting stuff. If I missed an easier way top do it, it's because I can't find it in the 30 different assemblies.

TreeHelper seems to have two methods for selecting nodes or documents. I don't see a difference.

Now I agree, generics are somewhat advance, but it would be sooo nice to have a List<Attachment> and each of them has a mime-type, extension, filename etc.

And a real weakness is the where statements. Trying to get documents in a certain category.. I think you know what I mean. That seems like it was a rushed feature. At that point I might as well start using SqlCommand myself! I have used LINQ to SQL, NHibernate and Entity Framework, writing queries is no longer my hobby as a programmer.

I see what you mean with an accessible API, but it's not efficient or productive enough for me at the moment.

Martin Hejtmanek commented on

Hi,

We have used unit tests in the past, but since our development cycle is quite short and we do a lot of changes, they seem to be not efficient, it just took a lot of time to update them so we handle this manually within our standard test suites for the modules. With the testing framework of VS 2008 and some other tools we are trying we are thinking about using them again.

A agree that generic programming is very powerful, I am a fan of that myself. But our solution must be as simple as possible from the developer point of view, and by that I mean beginners, with minimum knowledge of C# and ASP.NET. We actually get a lot of positive feedback on our current API, because it is a programming everybody is used to, even when you come from some other programming language, and can use it with knowing just the basics. Just think about this for a while, at which stage were you able to use generic classes? Was it at the very beginning, when the only thing you needed to know was how to call the method, or was it after you knew all the basics, sometimes later? We may think about this in the future, but in general, most of our clients are happy with the way it is now (actually, you are the first one I know about (except for myself :-)), who would like too see something like this).

Actually, this is something that you could very well do by yourselves (you seem to have a very good idea how this should look like), and it could be very well done using our current API, just by creating some abstract layer on top of it. If you believe this is something that lot of users would like, you may create this as a package for Kentico CMS and publish it on our Market place, get some money for that and maybe even win our $1000 price for the best contribution to the Market place if people really like it.

BTW, can you tell me what you thought was confusing about our API? If we can address these issues, we may improve the documentation that it is clearer.

Similar thing with LINQ, we have to support .NET 2.0 (not everybody already has .NET 3.5 and willing to go there) so we cannot use LINQ by default. Actually, being able to reference our database by LINQ is a matter of 5 minutes, you just install the 3.5 version by the web installer and add the LINQ references to the database and that's it. You can use it.

You know, there is always a lack of the development time for the things that aren't really requested by the majority of the users, because majority of the users is what keeps the revenue and the company living. So I agree that all of this would be really nice, but we just need to wait for some time before the entire audience is ready for that and willing to pay for that (or better, specifically requesting that). That's why we are on purpose a little behind the latest technologies, and just allowing them to use in our solution.

random0xff commented on

Hey, thanks for the response. If I may suggest the following:

I believe that with proper architecture a solution can become highly decoupled, thus you can do unit tests. Do you have unit testing in place for Kentico?

--

I agree on OSS projects. Looking at jQuery, there are a lot of plugins voor UI widgets (tabs etc), but when the jQuery team makes their own library of UI widgets it is much more stable and indeed more consistent across the whole library.

--

One thing too take into consideration for Kentico: the API is a bit confusing. Yesterday I experimented with generics and reflection. What I did was the following:

If you have defined a document type with fields in the CMS, let's say Custom.Thing with a field Name. You create a pure C# class (POCO) called Thing in the namespace Custom with the same fields. Then using reflection and generics I can wrap the Kentico API so you can do this:

Repository<Thing> repository = new Repository<Thing>();
IList<Thing> things = repository.FindAll();
Thing something = repository.GetById(25);
string name = something.name;

Just an experiment, you can take this as far as you want. If you develop this, you can get a very clean and consistent API, instead of the confusing TreeHelper/TreeProvider with the where argument and the LIKE /% syntax.

Let me know what you think, it's a win-win-situation for Kentico and customers. Clean wrapper API with clear documentation, and you can refactor underlying code if necessary. Maybe even start using LINQ in the API!

Martin Hejtmanek commented on

Hi, actually what you are refering to is more architectural, not a code itself. This is not really about following some guidelines (unless you are Microsoft programmer strictly following those Microsoft ones), it is only about following some practices (and their author is really not important). It it was, we would probably implement all the web sites with HTML and CSS features IE has, wouldn't we :-)? From the fuctional and extensibility point of view it doesn't really matter what naming conventions are used, these are just names for pointers, nothing else and the only thing which matters (regarding the names) is if you can understand what each of them means.

Think of this post as of something that assures you that all these things are somehow defined defined by the process, because it they wouldn't, the code just couldn't be good enough.

Please note that this article topic is not "Kentico CMS follows iternational standards and naming conventions", but just "Some comments on quality and readability of Kentico CMS's code", which is basically what 99% of our clients wanted to know. There is really nothing more in that and I never expected you to think that our code is the best in the world. It isn't, but it is good enough for the source code license to be worth of buying.

Same for the "Open source" statement. I never said that is 100% of cases and I certainly never meant to throw dirt on such solutions (that's why I am not pointing fingers and never will). I just said "it CAN be" because this is something that (again) most of the clients do not think of in their desicion process and the additional expenses for support and bug fixing exceed their original expectations. We actually have a lot of clients that came over to our solution from open source products just for the lack of support and quality assurance which caused them financial problems with their project budgets. I mean, there age good open source solutions and there are bad ones, but the good ones usually come with hidden costs at the end. (And again, usually, not 100% of the time)

What is your experience with Open source (I mean in terms of the larger and customized projects)? Mine is that they usually have a decent and very well written core, but when you start looking at the modules, in some cases each of them uses its own naming conventions (so you have to learn several of them for the entire solution), and they also may not really get along with other modules, which makes the solution problematic from both performance and stability point of view. (Also something that we hear a lot from our clients)

random0xff commented on

I think what constitutes good code is not what is discussed in this article. Good code follows the SOLID principles, these are:

Single Responsibility
Open-Closed
Liskov substitution
Interface seggregation
Dependency Inversion

Of course, while working you should always keep in mind:

DRY and YAGNI

So for me, a discussion of Kentico code and how these principles apply to it would be more useful. This article is not really convincing, here's a few reasons:

* All code is in the CMS namespace.
Please read the framework design guidelines from Microsoft, this is bad practice. The namespace should have been either Cms, or even better Kentico. And either way, the fact that code is in a namespace is by itself no guarantee for quality.

* Team Foundation Server is used.
EVERY single open-source product on SourceForge, Google Code, Github or Codeplex uses source control. This is NOT a USP for Kentico, and no guarantee for code quality.

* Regions
Well some people don't like regions. It's not indicative of code quality, since regions are not code.

* Naming conventions.
Again I refer to the framework design guidelines, this is a book from Microsoft with the guidelines you should follow. I have seen that Kentico code uses HUNGARIAN naming conventions for internal member variables. This is NOT good coding practice, it is explicitly warned against this in the official guidelines. In fact, it was practice from the VB6 times, and should be left in those times ;-)

* Of course we have some rules for HTML and CSS. Internal guidelines for HTML and JavaScript.
Ok, that sounds nice but in fact when we are looking at the current state of the art in JavaScript we should not be developing internal guidelines. We should be following best practices as taught by Jon Resig of jQuery and the incredible Douglas Crockford from Yahoo. skmMenu is really not state of the art JavaScript, nowadays we program with closures, even namespaces are possible in JavaScript.

To conclude, I (and many others) measure code quality in entirely different ways. I am not conviced that the Kentico code would pass on these metrics, but I can't know for sure until you comment on the principles above. Looking forward to a follow-up article or a reply!

Then again, for me it's not really that important, since I use Kentico in my free time to do some small work. But I would not professionally recommend until I know more of what I said above about Kentico code.

Thanks!

PS. This statement in the article is really not nice:

"Do not use free open source solutions or products of virtual companies in the projects, which you want to be good, because it can be a nightmare for you!"

The opposite can also be true!