quinta-feira, 18 de abril de 2013

My template .NET architecture

I don't intend to be very strict on the way things are build but there's always some positive and negative points to every architecture. I'll try to express my thoughts on the way I believe to be the most flexible and maintainable architecture for a .Net project on Visual Studio and hopefully justify my decisions in a clear way.

Here is a presentation with the information on this post:
https://speakerdeck.com/diogogcunha/dot-net-template-solution-architecture

The main objective is to have a solution that is
  • Flexible to change, add and remove features
  • Maintanable for many developers with different coding habits
  • Sustainable for growth
  • Understandable for code review and optimization
  • Easy to add new features with few lines of code without losing structure
  • Testable (unit and integration)
The basis for this architecture will follow the typical 3 layered solution

So the Frontend is only dependent on the Services Layer and the Services Layer is only dependent on the Data Layer. The Frontend shouldn't be able to call Data Layer objects without passing through the Services Layer logic.

Let's go bottom-up!

Data Layer

namespace projName.Data

This layer would be a new Project inside the solution and it is an abstraction for the data that the system writes and reads from different data sources. It should only contain CRUD logic and nothing else.


Repositories and entity objects should be here.

Entities

namespace projName.Data.Core.Entities

Entities are the raw domain objects that come from the data source. So if you are integrating with and external platform such as Facebook or if you are writing on a XML you should have that information in object classes so you have strongly typed entities.

A lot of .Net developers will use EntityFramework to do most of the work writing to the database. Using model first this is the place to put the .edmx file, using code first this is where you’ll put your DbContext file and your entities.

To be able to mock the DbContext or the ObjectContext you should do a wrapper around it (or a partial class) that use an interface and expose what you need.

Avoid unecessary dependecies using different projects under the same namespace.


Repositories

namespace projName.Data.Core.Repositories

Each entity should have it’s own repository. If the entity is read only so should be the repository.

All repositories must have their own interface and class and it is useful to have some generic abstract repositories to decrease the amount of code to be written.

Repository methods should be easily overriden for flexibility so we could make them virtual but it’s not mandatory because C# let’s you override a method with the [new] word on the function signature.



Read repository is probably the most used one, so we should try to make it as powerfull as possible. Also because LINQ is cool I’m copying some of it’s namings.

Creating, updating and deleting entities is usualy a fairly simple operation and it should remain so. No other kind of logic should be implemented in these classes except setting default values like , for instance a CreationDate = DateTime.Now;
In some situations the Update method is not necessary (if you use EntityFramework for some of your data) so don’t feel that obligated to implement this method, just leave the possibility there for other data sources that might need it.


Services Layer

namespace projName.Services

This layer would be a new Project inside the solution that references the Data project and it is where all the business logic should be centralized.



Services should be divided by actions oriented and also reading services or writing services, this will allow all writing services to be dependent on their corresponding reading services if needed (example: instead of a UserService use UserInfoService, UserEditService and UserAuthService) 

External modules should be added to avoid unwanted dependencies to the main .dll file


Unit of Work (Service Layer and DataLayer)

namespace projName.Data.UnitOfWork

A service will use the Unit of Work to access the data layer (the Unit of Work pattern is a class that has a reference to all the repositories and to the context in which these repositories work giving only access to the repositories and a SaveChanges method that commits the changes to the database).

Every service that needs to access the Data Layer will extend this class and (as the repositories) have it's own interface.

This should be implemented on a different Project so that when you reference the Services on the Frontend you don’t have access to the Unit of Work.


View Models

namespace projName.ViewModels

The view models should be another Project in the solution to be referenced by the services and Frontend.

Services only receive and return ViewModel objects that should have Frontend needs in mind and not domain entities to make them aligned with the operations they refer to.
Dividing the ViewModels into folders according to the entities they refer to will make the code more maintainable.

Mapping Entities to ViewModels and the other way around is probably the most boring code to write because it’s simply transforming one object to another one, so I usually use AutoMapper which is a very handy tool. 

There are several ways to do these mappings and I believe that the big concern here is performance and easily understand to which ViewModels does a Entity map to and how that mapping is processed, and the other way arround.


Frontend layer

namespace projName.Frontend

Frontend layer is where your services actually get exposed in whatever way you want.

It should be as easy to use a MVC.Net project on top of this architecture as it would be to use WebForms, WinForms or a Mobile App.

Again it is important to have clear namespaces in order for the project to grow if necessary so use names like  Frontend.Website, Frontend.Mobile or Frontend.Backoffice 


The end for now!!!

I think this is a nice solution because it already saved me from many situations of late requirements, weird integrations or pure stupidity from the part of the client or idiotic solution sugestions from managers because it has a lot of flexibility but it's still very simple to maintain and extend.

I've been told that it pretty much follows the Onion Architecture and from what I've read of it has the same principles! (thanks Nuno Costa for the cool input!)

sábado, 13 de abril de 2013

What's all this about, developing for managers?

Well I'm a software engineer and I've been working for some time now on the Web environment. I'm Portuguese and I worked in a place where I got the oportunity to build stuff for international clients. Now I'm  working in the Netherlands in the same area. I work a lot with .NET, Umbraco, MSSQL and Javascript but I try to know a little about every language that might be usefull, at least the basics.

Now, what do you mean by "developing for managers" one might ask.. the thing that I found to be something like a universal truth in my area is the fact that managers don't quite get the problems of a developer (especially if they come from a non technical background). This is especially true when, after you get some requirements and already built something, they ask for "that little change" that's going to mess all your poetry-like code.

I'll try not to bitch to much about managers here because the point of this blog is to make some notes on strategies and practices to work around, antecipate or solve some of these issues. Hopefuly I can help myself with a little reflection on my professional adventures and help others with some insights or just by making them know they they are not alone!! =P

So let me just define some concepts so that all that read this have the similar perspective.

  • Developer/programmer - person who is responsable for writing a piece of code (big or small, in one file or several files, in one language or several languages).
  • Architect - person who is responsable for the the design of a technical solution when given a list of requirements. This person will also be a Developer most of the times.
  • Manager - person who is responsable for the communication bridge between the techical team (Architect/Developers) and the Client. This person possibly is also responsable for project management (things such has managing the time of a project, resources, costs, expectations, etc).
  • Client - person or company who has a need for a technical implementation of a solution.

So... for me the thing that's most important when developing for managers is FLEXIBILITY and MAINTANABILITY because in reality most of the projects follow a strange flow of exponencial chaos.. at first everything seems to be well calculated and though out but as time goes by you'll get unthough situations and flows, requirements that magicaly appear or are "improved", design that gets changed or is just incomplete, etc etc.. Because the engineers are always the ones that need to come up with a solution (and if we don't, not only we'll hurt our ego =P, but also we "weren't up to the task"), we should try to make our own life easier by building a flexible and maintainable system.

Obviously these are not the only concerns to have when you're building a system, but in the perspective of "building for managers" I believe these come before all others (such as security, testing, performance, code consistency, system sustanability, etc).

I'm probably say some stuff here that some people won't agree (probably managers mostly but I expect also some techies to be outraged) and all input is welcomed, if you say things in a respectful way obviously.

Hope that I can make this not as boring as it sounds and bring some value to you, that are reading this. =)