I work in a .net c# application which contains 2 solutions for client and server. In server side there are 80+ projects that have been used to separate following Architectural layers,
Infrastructure Layer
Integration Layer (External Systems)
Domain Layer
Repository Layer
Manager Layer
Service Layer
In addition, almost every layer has test project.Now, the build time of the solution takes 2 to 3 minutes, and many developers (including me :)) feel we need to tackle this problem.
Therefore,proposed solution was to reduce the number of projects by merging the projects.In my view, it is probably a good solution to minimize the build time and we could achieve what we want.
Proposed solution is that we merge our projects into 3 areas, such as one library for production code, one library for test code, and one for deployment projects (WCF host ,etc) and logically divided layers in same project by separating the namespaces.
However, my concerns are
Could these separation good for the maintainability ? providing that more that hundread of classes for each namespace appox.
If we have common functionality such as helpers, where are we put those ?
Is there any other way to layering the solution ?
I guess you should split your solutions in logical layers.
As part of where do you put the helpers. Make a solution for it, on one of the lowest levels.
EXAMPLE
Software for a farm. You'll need to keep track of your animals, vegetables. You need a module for feeding the animals and one for Selling the animals and vegetables to the consumer market.
This could be splitted in a the following solutions
Back-end
Sell Module: Everyting for selling your products
Buy Module: Buying seeds, food for your animals, other products, ...
Sheduler Module: Trigger events for sow seeds, harvesting, ...
Prediction Module: Predicting harvests quantity's by the weather, and market prices, ...
...
Each of these back-end modules, can have it's own Data Access Layer, DTO, WCF Services, ...
This solution will only contain Business Logic, Data Access, ... . And there can be multiple front-end solution connecting to these back-end solutions.
Front-end
ASP.NET MVC Application: Webshop for selling to a consumer
WPF Application: Approving sells
Other WPF Application: Buying things.
Mobile application: Getting the events to your phone or something.
(Another option is to connect 2 or more backend solutions into 1 front-end solution)
...
This is a BIG change for your project and this will have an impact. Make sure you think this true, if you wan't to change it.
Multiple solutions will INCREASE your overall Build Time and it's important to have a nightly build so every developer can always work on the latest binaries, without having to build all the solutions on his local machine.
Note you can still use your layers in the different solutions:
Infrastructure Layer
Integration Layer (External Systems)
Domain Layer
Repository Layer
Manager Layer
Service Layer
To make this work all together and don't get messed up with binaries. You can map a drive I.E. X: where you have a folder binaries, where you have a folder for each solution. where each solutions copy's the assemblies on the post build event. (Script this, so it works on every machine)
If you have a good network infrastucture, you can also copy it on a server. So when you build all solutions for example in TFS, it can copy it to a location all developers can access.
If you build in TFS make sure your build order is correct, first the lowest layer, last the highest layer.
But as you split up your solution, in solutions you'll probably don't need them in every solution.
I recently read an article about Onion Architecture, maybe you can have a look at that too. (It's specific for ASP.NET MVC).
You can also have a look into CQRS.
Why 80+ projects while you only have 6 layers in your application ?
You might answer that they cover a large number of functional areas, but do you need all these functional areas in one solution in the first place ?
I'd recommend reflecting architectural divisions with projects and functional divisions with solutions. Different solutions can reuse the same projects. This way you'll have one project for each reusable architectural layer and as many Domain projects as there are functional areas.
I definitely wouldn't merge the projects... I think you'll quickly end up with spaghetti code in each layer as the developers take shortcuts (whether they mean to or not) that they shouldn't be taking.
I'd be more inclined to separate the layers out into separate solutions... and use binary references instead of project references across the tiers. This can play havoc with branching though, be careful.
I've seen build times drop by making the projects build to a common place - apparently this can prevent VS rebuilding projects when it doesn't need to - but I don't know if this is true or not.
Some ideas here: http://blogs.microsoft.co.il/blogs/arik/archive/2011/05/17/speed-up-visual-studio-builds.aspx
Finally.... is the three minutes for a full build or just to unit test one project? Focus on whichever is the biggest issue. If unit testing is taking a long time, you've got a problem with dependencies. If the full solution is taking a long time, get a build server and focus on bringing your unit test development time down.
Hope that helps
A low impact way I've dealt with a problem like that in the past is to create a series of solution files that include just one of the projects and its test project (and perhaps the project's dependencies). Then, get yourself a tool like NCrunch and do most of your coding in these solutions, probably using TDD. This will give you lightning fast feedback loops and is decidedly in the spirit of the layered, decoupled approach. When I've done this in the past, I find that I only actually run the entire application a few times a day, max, and I rely heavily on red-green-refactor, which is nice anyway.
If you want, you don't even have to source control these little solution files -- developers can create their own and they can be borderline throw-away.
Of course, this is by no means a panacea and won't address the problem of long compile times when you want to run the application, but it can definitely help simultaneously cut down on feedback time while promoting good design/development practice and it has the advantage of being extremely low risk and fast to setup.
Related
We have a number of small ASP.NET MVC apps. All are basically a bunch of forms which capture data and store them in a SQL Server database, usually which are then loaded through to our datawarehouse and used for reporting.
We are looking to rewrite all the small applications and apply a level of consistency and good practice to each. All the applications are fairly similar and I think from a user perspective it would be better if they seemed to be part of the same large application so we were considering merging them together in some way as part of the re-write.
Our two currently preferred options seem to be:
Create a separate portal application which will be the users point of entry to the apps. This could have 'tiles' on the homepage, one for each of the apps (which would be registered in this parent app) and could link them through to all. In this scenario all the Apps would remain in different projects and be compiled/deployed independently. This seems to have the advantage of keeping the separate so we can make changes to an app and deploy without affecting the others. I could just pull common code out into a class library? One thing that annoys me about this is that the parent app must basically use hard coded links to link to each app.
I looked into using 'areas' in ASP.NET MVC and have all the small apps as different areas in one big project. This seems kindof cleaner in my head as they are all in one place, however it has the disadvantage of requiring the whole app deployed when any of the individual ones are changed, and I have a feeling we will run into trouble after adding a number of apps in to the mix.
We have a SharePoint installation and someone suggested creating the portal type app in SharePoint... This doesn't sound like the best idea to me but am willing to consider if anyone can point out advantages to this method.
Are there any recommendations on the architecture of this? Has anyone completed similar projects in the past and something worked well/not well?
We have 4 developers and we do not expect the apps to change too much once developed (except to fix potential bugs etc.). We will however plan to add new apps to the solution as time goes on.
Thank you
MVC Areas advantage would be allowing code sharing, by refactoring the repeated redundant parts of each app to use the same infrastructure code (security, logging, data access, etc.)
But it will also mean more conflicts when merging the code initially.
Deployment concerns can be mitigated with a continuous deployment tool (there are many in the market) or if you deploy to an Azure WebApp, then deployment slots can give you a zero down time deployment.
As I'm typing this, I'm realizing that it's very hard to explain. My apologies if it's indiscernible. My end goal is to have someone with more experience look at how I'm structuring my solution and provide feedback on whether or not it is an acceptable setup.
I currently manage several small support projects that are loosely related to one another. They are all over the board. I want to create a unified INTERNAL-WEB application to manage these projects. I've managed to group everything conceptually into three domains. SHIPPING, EXTERNAL-WEB, INTERNAL-WEB. From a business perspective, SHIPPING sends WIDGETs to CUSTOMERs which then connect to EXTERNAL-WEB. The problem is that SHIPPING's definition of WIDGET and CUSTOMER is different than the EXTERNAL-WEB definition, so I need to break these two apart.
After some thinking, I've come to the conclusion that the best way to organize this in VS2010 is to create a solution and then nest multiple projects within the solution. I'm envisioning a layout like the following.
SOLUTION
---SOLUTION.SHIPPING.Domain (Classes)
---SOLUTION.SHIPPING.Infrastructure (Classes)
---SOLUTION.EXTERNAL-WEB.Domain (Classes)
---SOLUTION.EXTERNAL-WEB.Infrastructure (Classes)
---SOLUTION.INTERNAL-WEB.Domain (Classes)
---SOLUTION.INTERNAL-WEB.Infrastructure (Classes)
---SOLUTION.WebUI (MVC3 Project)
I'll have to add additional projects for context maps and anti-corruption layers to allow communication between domains, but this is the basic layout.
Is this smart or is it stupid?
Thanks,
Greg
How you have configured your solution has nothing to do with DDD and won't effect the success of your project. Good code that is organized badly is much better than bad code that is organized well.
Projects have a productivity and complexity cost associated with them. Right now you are agonizing over details which don't really matter.
More projects also equals slower compile times which increases context shifting. Try reading a book and pausing for 30 seconds every page.
New projects should be created for either deployment or code sharing purposes. Good reasons include if the domain is shared between two front or if you have a monstrous deployment strategy ( 1000s of machines ) and megabytes still matter.
Once you simplify the rules for new projects the decisions start to be made naturally as the codebase matures and new requirements pops up. You are essentially making physical decisions at the last possible moment. This is good. Don't BUFD this when you have features and code to write!
Not sure why this question is tagged MVC but the MVC codebase is pretty lean with only 1 main project. Compiles fast and is really easy to navigate around.
When/where do you decide to split a large Visual Studio project into smaller multiple projects? If it can be reusable? when project is too big? (but how big is too big?)
and When you do split the project, do you,
group by database tables
group by similar functionality
other..
Pros of many projects:
Easier to isolate code for unit testing. I like to isolate code that has a dependency on a big external server thing, for example code that talks to the SMTP server gets its own assembly, code that talks to the database gets it's own assembly, code that talks to the webserver, code that is pure business logic like validations.
Pros of few projects:
Visual studio goes faster
Some developers just don't get your vision
about dividing up responsibilities
and will start putting classes
everywhere, so you end up with the
pain of extra projects and the
benefits of putting everything into
one project.
Each project has a configuration and when you make a decision about project configuration, often you have to make the same chagne everywhere, such as setting or changing the strong name key
Pros of many Solutions
You hit the maximum project level later.
Only the stuff in your current solution gets compiled everytime you hit f5
If the project isn't expected to change in the life of your application, why re-compile it over and over? Call it done and move it to its own solution.
Cons of many Solutions
It's up to you to work out the dependencies between solutions and manually compile the dependencies first. This leads to complicated build scripts.
Projects should be cohesive. Logic should be related, and accomplishing a similar goal
This answer will depend on the size of the product you are supporting. In general we organize our projects along domain and logic. And we will divide those even further, the more you divide the more organize you must be, or you are going to hit the dreaded recursive dependency issue.
When I do choose to break up project it is when it grows to be too large or two areas are becoming too similar.
When complexity is rising I do not split by tables, i generally split functionality.
Re-usability is another excellent time to reduce lines of code, as well as introduce a new project. However be careful how many "utility" libraries you introduce because they do have impact on readability/understandability.
I do not think there is a line in sand that says, if you hit 3k SLOC, you have too much. It all is contextual.
I always have several projects (and therefore a solution) , instead of one project with all of my source in it.
In some cases, it is unavoidable because you are using and open source library and want to be able to debug it. But more pragmatically, I typically have my applications provide functionality via plugins. This allows me to change the behavior or offer a user-selectable behavior at runtime. In the non-plugin case, it allows you to update one portion of your program without updating everything. There are also cases where you can provide the main apparently, and only download the modules / assemblies when you need them.
One other reason is that you can create smaller test apps to exercise an assembly, rather than building a very large solution and potentially requiring a user to execute several (and irrelevant) GUI operations before even reaching the part you want to test. And this isn't just a testing concern -- maybe you have less-savvy users in your organization that only want to be presented with the bits that concern them.
When the overall purpose of the project remains the same, but the number of classes is becoming large, I tend to create folders and namespaces to better group functionality within the project. Classes that are coupled to each-other tend to go in the same folder/namespace, so that if I need to understand a given class, the related classes are nearby in the Solution Explorer. I usually only create new projects if I realize that a particular piece of functionality is very different in purpose or if there is a common dependency between existing projects.
I usually wind up with a few relatively small Framework projects that define interfaces for loose coupling between other projects, with larger projects for the different types of concrete functionality. That's always at least one project for the UI and one project for logic and data (often split into two projects if the data layer becomes very large in its own right.)
I move code to a new project, if it has general functionality (theoretically) usable by other projects too. If the project is large, because it represents a complex problem, then namespaces provide a great way to bring order in the code. Here you can for example introduce a (sub-)namespaces for each SQL table, etc. etc.
Currently I'm working with a big, old and extremely poorly written ASP.NET 1.1 application and the continuous maintenance is becoming quite a problem. Basically it's reaching breaking point and I'm reluctant to expand it any more than I have to as demanded by the business. Based on my experience creating other projects from scratch it would really suit an ASP.NET MVC based solution. Oh how I wish the world were that simple...
The fact is that I just cannot justify re-writing it from scratch and the business cannot afford it. The ideal solution would be to start writing an MVC-based application alongside it and begin a slow migration as new requirements arise.
I've read posts which state that this is entirely possible, but in my experiments I've not found it so easy. The current application contains several large data access and business logic layers shared by other applications that the company produces. These are also written in 1.1 and will not compile in 2.0 (and would destroy the other projects if I tried!) so I cannot upgrade them. Since I can't do that I'm stuck with an application that cannot even be opened in a .NET 3.5 capable visual studio. The new MVC app would also have to make use of these layers.
I am entirely open to suggestions. I'm desperate to find a solution that I can quickly demonstrate would allow me to improve the product immensely without taking too much time or affecting the rest of the business.
You could write a WCF service on top of the existing business layer and have your new app talk to that service instead of referencing the business layer directly.
You need to divide to conquer. Analyse the current app and its layers and see if you find a way to divide each significant piece of functionality into a discrete area with as few changes as possible.
Then make each area a unique service using the old technology.
Then you can rewrite each service slowly as you can fit it in and not affect the whole.
Otherwise you are going to have to come up with a convincing business case for your managers so that they allocate you the time to do the job properly. Sometimes our job is political as well as technical.
We have a base product that has bespoke development for each client that extends and overwrites the functionality of the base.
We also have a custom framework that the base product and sits on top of.
We use inherited forms to override the base functionality and to date all the forms and classes have been lumped in the same projects i.e. UI, Data, Business...
We need to clean up the code base now to allow multiple client project to run off the base product at once and I was looking for advice around the following areas:
Ways of organising the solution to fit with the above requirements, the number of projects in the solution is quite large and we want to reduce this to increase developer productivity, we are think of making the Framework DLL references instead of project references
Are there any build and deployment tricks we are missing, we currently have a half automated build and release process
What is the best way to manage versioning
Any best practices for product development
I personally strongly believe that highly modular architecture will fit here nicely: core application should provide basic/common services, and all customer-specific functionality should be implemented as plug-ins (think MEF). Hence, several thoughts:
I'd go for one solution for core application plus additional solution for each and every customer.
One-step build is a must. Just invest some time in writing a handful of MSBuild scripts: this will pay off tenfold.
See APR's Version Numbering for inspiration.
Too broad a question.
I can give you an advice on your first question and maybe a little of the forth : If i were you I would go with a framework DLL solution that could easily be managed and futher developed by a team and different solutions for each subsequest project. However, the framework solution would have to be propely developed, with extra care to one design principle: Open/closed principle [1] so future development of the framework does not break the existing implementations.
[1] http://en.wikipedia.org/wiki/Open/closed_principle