7

I'm looking for some advice on how I should arrange a large new project I'm working on to allow it be more easily managed in Git (using GitLab), and developed in Visual Studio.

To give an idea of scale, this is an entire server backend which'll consist of some networking services (sockets), data processing services, and web services. Each of these services will be an individual project, but there is going to be a lot of common code involved which I'll want to separate and between them (i.e. shared assemblies).

So let's say I have the following Visual Studio projects, with the shown dependencies:

Utility
SharedSocketCode - [ Utility ]
SocketServiceA - [ SharedSocketCode ]
SocketServiceA.WindowsServiceHost - [ SocketServiceA ]
SocketServiceA.ConsoleHost - [ SocketServiceA ]
SocketServiceB - [ SharedSocketCode ]
SocketServiceB.WindowsServiceHost - [ SocketServiceB ]
SocketServiceB.ConsoleHost - [ SocketServiceB ]
DbEntityModel
DataLogServiceA - [ DbEntityModel, Utility ]
DataLogServiceB - [ DbEntityModel ]
SharedWebServiceCode
WebServiceA - [ SharedWebServiceCode, DbEntityModel ]
WebServiceB - [ SharedWebServiceCode, DbEntityModel ]

As you can see, there is going to be a lot of shared code, and this is just the tip of the iceberg! I'm torn between storing all of this in the same repository, or trying to split them into individual ones.

The former sounds like the easier to maintain as I won't have to wrestle with Visual Studio looking for shared code in what could be different locations on each user's local version - the projects will all be predictably stored at solution-level.

The latter sounds like it'll give me more control over versioning each component and logically separating out what would otherwise be a single mammoth code base.

I'm quite new to Git and GitLab, so I'm not sure if there is anything that can help with this kind of scenario. Any advice would be welcome.

(FYI, I've added the GitHub tag as I gather it is reasonably similar to GitLab so there may be some assistance I can get from its users too)

  • 1
    Hint: take a look at Git Submodules, maybe it will fit with your setup. – Radu Murzea Feb 20 '15 at 12:43
  • 4
    Hint: take a look at all the controversies around Git Submodules before using them in production – Kos Feb 20 '15 at 14:23
  • Thank you both. I've opted to split the shared code into there own repos and just suffer through the initial pain where everything will be in flux. – Barguast Feb 20 '15 at 21:11
  • 4
    You can keep them as separate repositories and share them via a package manager (like a local nuget repository). This eliminates the ambiguities in referencing code from outside your repository. – antlersoft Feb 20 '15 at 22:41
  • Ah, that's brilliant! I'll definitely look into this. Thanks. – Barguast Feb 20 '15 at 23:29
1

I think you are doing great by splitting your Visual Studio Solution into several Projects that are creating libraries - as you and @antlersoft said in the comment.

This way you can have several other Solutions or even projects that create a standalone binary (like command line exe) referencing these library (Solution Explorer: add reference).

The one thing that git or Visual Studio is not doing for you (as the software architect of one or several solutions) is to untangle the references back and forth between your modules (I use this synonymous to library here).

It is a good idea to have a layered architecture in every bigger software system. When you go and re-architecture your whole system, you can follow these best practices:

  • create a namespace for each library that spreads across all the source files in this library
  • check the usage: which .cs file (and therefore it's namespace and the library that is compiled as a separate project) uses the class(es) in this library
  • assign every namespace/library to one layer (you don't have to give names to the layers); you could do this on paper or use any UML tool that supports component diagrams (including the one in the higher valued Visual Studio Versions; some UML tools call it explicitly layer diagram)

At the end of the day, a good architecture is achieved if no library of a certain layer is using any library in a layer above (no upwards pointing arrows) or the same layer (sidewards pointing arrows). If you can't get this done easily you can go for the weaker form of allowing same layer access.

{ If you download the preview version of Visual Studio "15" (which is a ultimate VS; as long as it is still available) you can open your project and pick New Diagram from the Architecture menu (right next to Tools), chose Layer Diagram and play a little bit around - there is a how-to video linked after you created your first diagram. The following screenshot shows the generated diagram that you get when you drag in some of your libraries from the Solution Explorer, right-click on it and select generate dependencies. }

LayerDiagram to show as implemented in Visual Studio "15"

The following refactorings help you getting there:

  • Move a whole class to a different namespace/library
  • move a property/field up or down the inheritance hierarchy to move the dependency that originates from accessing this property/field into a different namespace
  • move a method up or down the inheritance hierarchy for the same reason
  • do some additional classification by a) adding a more general superclass that contains only the a subset of the properties/fields and/or methods or by b) creating more specific subclasses

The process of re-architecturing or refactoring your system to resolve inter-library (package/namespace/module) dependencies that prevent you from reusing your existing software in additional projects has produced a very significant amount of publications. I called it untangling above which is not really the scientific term. One outstanding book reference that covers this (and was written way before git times but is still a very good source) is the Gang-of-Four Book which uses the term software design (as in object oriented analysis and design). You can also find some very good books or articles using re-architecturing or just architecture or refactoring in your favorite book store or search engine.

Just to reconfirm again: once you re-adjusted the project lines this way, each project is a good candidate for also being used as a git repository and you can check it out to any number of additional solutions you want to reuse this library in.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.