C# – How to best to organize class and interface files

cclasscode-organizationinterfaces

OK .. after all the discussion I'm changing my question slightly to better reflect a concrete example that I am dealing with.


I have two classes ModelOne and ModelTwo, These classes perform similar type of functionality but are unrelated to each other. However I have a third class CommonFunc that contains some public functionality that is implemented in both ModelOne and ModelTwo and has been factored out as per DRY. The two models are instantiated within the ModelMain class (which itself is instantiated at a higher level etc – but I am stopping at this level).

The IoC container that I am using is Microsoft Unity. I don't pretend to be an expert in it, but my understanding of it is that you register a tuple of interface and class with the container and when you want a concrete class you ask the IoC container for whatever object matches a specific interface. This implies that for every object I want to instantiate from Unity, there has to be a matching interface. Because each of my classes performs different (and-non-overlapping) functionality this means that there is a 1:1 ratio between interface and class1. However it does not mean that I am slavishly writing an interface for each and every class I write.

Thus code wise I end up with2:

public interface ICommonFunc 
{ 
}

public interface IModelOne 
{ 
   ICommonFunc Common { get; } 
   .. 
}

public interface IModelTwo
{ 
   ICommonFunc Common { get; } 
   .. 
}

public interface IModelMain 
{ 
  IModelOne One { get; } 
  IModelTwo Two { get; } 
  ..
}

public class CommonFunc : ICommonFunc { .. }

public class ModelOne : IModelOne { .. }

public class ModelTwo : IModelTwo { .. }

public class ModelMain : IModelMain { .. }

The question is about how to organize my solution. Should I keep the class and interface together? Or should I keep classes and interfaces together? EG:

Option 1 – Organized by class name

MySolution
  |
  |-MyProject
  |   |
      |-Models
      |   |
          |-Common
          |   |
          |   |-CommonFunc.cs
          |   |-ICommonFunc.cs
          |
          |-Main
          |   |
          |   |-IModelMain.cs
          |   |-ModelMain.cs
          |
          |-One
          |   |
          |   |-IModelOne.cs
          |   |-ModelOne.cs
          |
          |-Two
              |
              |-IModelTwo.cs
              |-ModelTwo.cs
              |

Option 2 – Organized by functionality (mostly)

MySolution
  |
  |-MyProject
  |   |
      |-Models
      |   |
          |-Common
          |   |
          |   |-CommonFunc.cs
          |   |-ICommonFunc.cs
          |
          |-IModelMain.cs
          |-IModelOne.cs
          |-IModelTwo.cs
          |-ModelMain.cs
          |-ModelOne.cs
          |-ModelTwo.cs
          |

Option 3 – Seperating Interface and Implementation

MySolution
  |
  |-MyProject
      |
      |-Interfaces
      |   |
      |   |-Models
      |   |   |
      |       |-Common
      |       |   |-ICommonFunc.cs
      |       |
      |       |-IModelMain.cs
      |       |-IModelOne.cs
      |       |-IModelTwo.cs
      |
      |-Classes
          | 
          |-Models
          |   |
              |-Common
              |   |-CommonFunc.cs
              |
              |-ModelMain.cs
              |-ModelOne.cs
              |-ModelTwo.cs
              |

Option 4 – Taking the functionality example further

MySolution
  |
  |-MyProject
  |   |
      |-Models
      |   |
          |-Components
          |   |
          |   |-Common
          |   |   |
          |   |   |-CommonFunc.cs
          |   |   |-ICommonFunc.cs
          |   |   
          |   |-IModelOne.cs
          |   |-IModelTwo.cs
          |   |-ModelOne.cs
          |   |-ModelTwo.cs
          |
          |-IModelMain.cs
          |-ModelMain.cs
          |

I sort of dislike option 1 because of the class name in the path. But as I am tending to 1:1 ratio because of my IoC choice/usage (and that may be debatable) this has advantages in seeing the relationship between the files.

Option 2 is appealing to me, but now I have muddied the waters between the ModelMain and the sub-models.

Option 3 works to separate the interface definition from the implementation, but now I have these artificial breaks in the path names.

Option 4. I took Option 2 and tweaked it in order to separate the components from the parent model.

Is there good reason for preferring one over the other? Or any other potential layouts that I have missed?


1. Frank made a comment that having 1:1 ratio harkens back to C++ days of .h and .cpp files. I know where he is coming from. My understanding of Unity seems to put me into this corner, but I am also not sure even how to get out of it if you are also following the adage of Program to an interface But thats a discussion for another day.

2. I have left out the details of each objects constructor. This is where the IoC container injects objects as required.

Best Answer

Since an interface is abstractly similar to a base class, use the same logic you would use for a base class. Classes implementing an interface are closely related to the interface.

I doubt you would prefer a directory called "Base Classes"; most developers would not want that, nor a directory called "Interfaces". In c#, directories are also namespaces by default, making it doubly confusing.

The best approach is to think about how you would break up the classes/interfaces if you had to put some into a separate library, and organize the namespaces/directories in a similar manner. The .net framework design guidelines has namespace suggestions that may be helpful.