Why and when to create a project library in .NET?

Why and when to create a project library in .NET?

I’ve interacted with many different business systems that have their solution broken up differently in respect to the number of project libraries.  And I’ve discussed this with developers and it seems everyone has their own opinion.  I’ve thought a lot about this and I’m to discuss my opinion.

Here are some reasons that I can think of why you may want to create a new project library:

  • For organization purposes, reduce complexity, Single Responsibility Principle, encapsulation and decoupling code. 
    • This is useful if you want to keep a library self-contained easy to comprehend.  There is less code to have to comprehend at once.
    • You can hide code from other systems from misuse.
  • Limiting amount of deployed code.  Limit the size of libraries. 
    • This is useful if you want to limit the size of the binary that is deployed and executed. 
  • For limiting dependencies.
    • This helps make it easier to modify code.  Less dependencies me less code will be impacted by changes.
  • Limiting references
    • This is a negative reason to create a project.  The more projects you have the more likely you will have to add duplicate references.
  • For security purposes.
    • This is useful if you want to secure code from just anyone accessing it.
  • For critical code purposes.
    • This is useful if you want code to be performant and not be susceptible to bugs from other code changes.
  • For functional purpose such as specific layer and for controlling layer access.       
    • Makes it easier to switch out layers and layer specific frameworks.
    • Reduces framework dependencies.
  • For avoiding merge conflicts.
    • With many developers working on a code base, the more libraries help reduce merge conflicts.
  • For avoiding unnecessary builds and limiting change impact.
    • More libraries means that not everything needs to be built .
    • In visual studio, too many projects can lead to build order issues and poor build performance.
    • If something not changing then it might mean a lower probability of introducing bugs.
  • For common, reusable code that rarely changes.
    • This is useful for functionality that you rarely need to review and look it. 
    • The more code like this the better.  Projects like this do not necessarily need to be in the solution but can be referenced as DLL.

Here are some ways I’ve seen business and data libraries organized

1.       One BLL, One DAL

  • This one leads to too much tightly coupled code.  It fails the single responsibility pattern.  There is no encapsulation.  It mostly doesn’t limit dependencies.  It limits the ORM framework to DAL.
  • Lowers Project/DLL count

2.       Multiple BLL and DAL for each domain

  • Limits dependencies though DAL is available to all.  It reduces coupling of domain and layers.
  • Increases Project/DLL count.

3.       Multiple domain with both BLL and DAL included

  • It reduces coupling of domain.
  • It limits dependencies except EF is available to business.
  • It encapsulates DAL from external access.
  • Less Projects/DLLS than multiple DLL solution.

I tend to not like #1 because everything is accessible to everything.  The is no access control in place.

Number 2 is better than #1.  The only thing is I don’t see too much benefit in having the DAL broken out.  Maybe there is some Unit Testing or analytic benefit.  With #2 there is also an increase in the number of DLLS.  This style should limit the number of DLLS to a few high level areas.

I personally lean towards #3 “Multiple domain with both BLL and DAL included” because it limits access to code.  And the amount of code can be reduced such that it is easier to comprehend.  I think it is a good comprise between #1 and #2.  I tend to think in terms of how distributed systems are organized and this seems to line up with that. 

In general, I want projects where I can control access to the code.  I want code that is easy to maintain, which doesn’t have a ton of dependencies that I have to review and comprehend before making a change.  I want to be able to write code and forget about it as other code uses it. 

At the same time I don’t want a lot of libraries in a solution.  I want quick build and deploy times and small DLL sizes.

I may follow this up with a Part 2 discussion.

 

 

 

Type Sharing – Data Access Layer

To start off my “Code Structure” tag, I usually find developers create a big type library to hold all their types used across multiple libraries.  In my opinion, this violates the “Separation of Concerns” rule.

Another problem with this is developers tend to misuse the types and tightly couple code together such that a change to the type can potentially impact multiple areas.

For example, I’ve seen types meant for web service contracts used all the way down in the data access layer.

Another issue I’ve seen is types that have a ton of fields.  In many cases they have most of the fields in the corresponding database table.  By the way, I don’t necessarily believe that the types have to match the database table structure. 

I believe this issue is also what is described as the “God Class”.  Anyway one problem with this is that it can be confusing in code as to whether the objects of this type have been properly populated.  The default thinking should be it is always correctly populated by the data access layer but of course I’ve seen developers reuse a type and only partially populate the object.  They probably did this inadvertently from not thoroughly reviewing their code. 

So at least when coding in the data access layer and Update/Add APIs, I believe we should carefully select what fields are passed in.  All parameters and objects fields passed in should be assumed to be the exact values that will be stored in the database.

There are a few other issues with these “God Classes”.  One is type fields that are for calculations.  There is no good reason to pass these to the data access layer and cause confusion when reading the data access layer code.  Another issue is there is unnecessary payload being passed around.  And finally, the more fields you have to consider the more complex the API can be. 

Ideally, the data access Update/Add APIs should be simple processing of related data.

Code Structure

It’s impressive how much information there is on software development on the internet.  You don’t have to read books in order to develop applications.  It’s amazing how knowledgeable people are able the many programming languages and technical matters and how experienced they are.

But there is one thing I don’t see much of and that is how to organize code and projects.  And how to select the best third party libraries and solutions.

I have read many of the books and articles about the different ways you can solve problems.  There are all the different design patterns and architecture patterns.  Some of my favorites are

  1. Clean code
  2. Design Patterns – Elements of Reusable Object-Oriented Software.
  3. Refactoring To Patterns
  4. Patterns of Enterprise Application Architecture
  5. Patter-Oriented Software Architecture
  6. Refactoring

And I have some favorite Architecture Books

  1. Software Architecture In Practice
  2. Just Enough Software Architecture
  3. Software Architecture For Developers
  4. Documenting Software Architectures

And I luckily I read Code Complete back when I started my development career.

But there’s not much available on how to structure your projects and your libraries.  And what are the pros and cons of all the different ways that this has been done.

The most common structure I’ve experience is the multi-layer pattern.  It seems to be the most suitable and encourages “Solid Code”.

Anyway, when I have some special insight, I’ll be sharing my thoughts as to what seem to be best practices to me in organizing and structuring code.