Skip to main content

[Code refactoring] Class name and namespace with the same name (deadly sin)

Looking over some ‘old code’ (3-4 years old) I discovered a class nested under a namespace with the same name. For example we have a class called Foo and the namespace above is also called Foo
App.Foo.Foo
In that moment I told to myself something is not okay and we need to do something to change this. The good part was that this class was in internal class, used by other subcomponents – no public API there. I don’t know how I missed this problem until now.
The fix was very simple, renaming the namespace to a more suitable name.
Let’s see why we shouldn’t have a class and a namespace with the same name.
First of all you will have problem referring the namespace and the class. You will have to use the full namespace for the class or an alias. This can create confusion to developers, especially because they will never know when the class is referring or what the alias is. You can have different standards to name an alias but the scope is not to hack the system.
Namespace are used to group different classes, functionalities and so on. Theoretically you hope to get a code that is more easily to change, understood and maintain. When you and up with a namespace and a class under it with the same name than grouping will not help you. You will have an ambiguous namespace and class for all people that will try to use or understand the code under that namespace or code that use it.
When we have a good groping (based on namespaces) you will end up with a hierarchical namespaces, classes and a design that could be read pretty easily.  When someone will try to look over the hierarchical namespaces, he will end up with App.Foo.Foo and will say WHAT? He will need more time to understand why the class is called in the same why us the namespace. Because of this all the concept of grouping the classes using namespaces to organize and for easy understating will fall apart.
In the end, you will end up with a lot of name collisions. You don’t know what and where you are referring. The code will contain a lot of places where you are referring a class based on the full namespaces.
In conclusion I would like to say:
NEVER AND NEVER NAME A CLASS WITH THE SAME NAME AS NAMESPACE! THIS IS ONE OF DEVELOPERS SIN

Comments

  1. It's certainly a bad practice but I wouldn't go as far as to say that it's a "sin". The C# language offers several ways in which you can work with such an organization by using either the full name up to even the global keyword (i.e.: global::MyCompany.Foo.Foo) or through the 'using' directive.

    ReplyDelete
    Replies
    1. Usually you we end up with this issues (namespace and class with the same name) because of lack of inspiration - We don't know how to name our namespace or class correctly.
      In general we have a lot of options, a lot of names that we can use. Yes, there are different ways for workarounds (global, allies), but you don't resolve the real problem - why we ended up in this way.
      Until now I don't remember to find a .NET Core library with this problem. For code that is automatically generated, there we cannot do anything, this is it.

      Delete
    2. Yes Andrei, you can work around this problem, but just because "you can", it doesn't mean that "you should".

      Delete
  2. I think this is more of a limitation of the IDE rather than anything else. Namespaces are not a real part of the language, you can't really do much with the namespace; and the IDE should help rather than go in your way when you use the same namespace and name.

    Thing is, I tend to move to a namespace of its own when a class starts to grow too much; it makes sense that the namespace should have the same name with the class; then I will refactor things into place; but even then, I might have a core implementation named as the namespace.

    X.Foo.Foo happens naturally during refactorings. I don't find it a sin at all.

    ReplyDelete
    Replies
    1. A namespace with a single class inside it's a bit weird.. (if it's not still under development and more classes are going to be added to that namespace).
      Anyway, classes with the same name as the namespace can indeed happen accidentally when grouping several classes together, like:
      [Company].[Product].ShoppingCart.ShoppingCart :)
      when there are many other related classes in the ShoppingCart namespace..

      Delete
    2. @Tudor, in your example, if your namespace is ShoppingCart, than you can rename your class from ShoppingCart to Cart. You are already under a namespace that contains classes related to ShoppingCart.

      Delete
  3. Indeed, at least pluralization in the namespace could save the day: System.Windows.Forms.Form :-)

    ReplyDelete

Post a Comment

Popular posts from this blog

How to check in AngularJS if a service was register or not

There are cases when you need to check in a service or a controller was register in AngularJS.
For example a valid use case is when you have the same implementation running on multiple application. In this case, you may want to intercept the HTTP provider and add a custom step there. This step don’t needs to run on all the application, only in the one where the service exist and register.
A solution for this case would be to have a flag in the configuration that specify this. In the core you would have an IF that would check the value of this flag.
Another solution is to check if a specific service was register in AngularJS or not. If the service was register that you would execute your own logic.
To check if a service was register or not in AngularJS container you need to call the ‘has’ method of ‘inhector’. It will return TRUE if the service was register.
if ($injector.has('httpInterceptorService')) { $httpProvider.interceptors.push('httpInterceptorService&#…

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine:
threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration:

TeamCity.NET 4.51EF 6.0.2VS2013
It seems that there …

Run native .NET application in Docker (.NET Framework 4.6.2)

Scope
The main scope of this post is to see how we can run a legacy application written in .NET Framework in Docker.

Context
First of all, let’s define what is a legacy application in our context. By a legacy application we understand an application that runs .NET Framework 3.5 or higher in a production environment where we don’t have any more the people or documentation that would help us to understand what is happening behind the scene.
In this scenarios, you might want to migrate the current solution from a standard environment to Docker. There are many advantages for such a migration, like:

Continuous DeploymentTestingIsolationSecurity at container levelVersioning ControlEnvironment Standardization
Until now, we didn’t had the possibility to run a .NET application in Docker. With .NET Core, there was support for .NET Core in Docker, but migration from a full .NET framework to .NET Core can be costly and even impossible. Not only because of lack of features, but also because once you…