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.
Related
I am new to SpecFlow and I am wanting to reuse steps/tests (.feature files essentially) between solutions. I know there is a way to reuse steps between projects in the same solution by adding a reference to the project but I'm not sure exactly how to do essentially the same thing to a different solution. Thanks for any help on this one.
You cant reuse .feature files but you can reuse step definitions and hooks.
You will have to add reference to the project.
Here is the link how to reference a project in Visual studio: Link
I do not think it is possible to use steps from a different solution. You will need to include them in your working solution somewhere to use them. I don't think Visual Studio has the option to let you use inter-solution code unless you have compiled it and reference it within your working solution.
Doing this is a bit of an anti pattern. The reason for having feature files is to talk about WHAT the application does and WHY its important. So feature files should contain things that are unique to your application domain, and there won't be much overlap between projects
When you write features this way even common functionality isn't really worth sharing, because the complexity outweighs the simplicity of doing things again.
For example logging in is ripe for sharing between applications but all you need in a feature is
Given I am registered
When I login
Then I should be logged in
This is so simple that its easier to just write another one for your second application.
Most steps that people have shared other the years are all about HOW things are done e.g. clicking on things, filling in fields etc.. These generally lead to bloated scenarios and again the cost outweighs the benefits.
If you still feel there is alot of shared behaviour between your applications you may have an architectural problem where you need to extract the shared behaviour into its own application, and have your applications delegate responsibility.
I hope this is not an obscure question. I expect there are several ways people accomplish it and the approach I'm using seems excessively labor-intensive.
How do I break apart a presentation-layer project (XAML/WPF) into several temporary "side-by-side" projects so that I can make enhancements efficiently in VS 2015 and unit-test them quickly? The end result being that, once the unit tests are successful, I combine the projects back as they were again (with a focus on organization rather than developer efficiency).
The problem for me is not one of analyzing the inter-dependencies, not one of identifying project boundaries, and not one of adding the newly created (temporary) project references where needed. The biggest problem I have is with all the silly XAML namespace references (clr-namespace:). They need updating so they will point to the new home assemblies (assembly=) for the referenced resources. This is a ton of overhead and doesn't always have a pay-off since it is temporary work in the first place. Where is the tool to do this for me? And revert it back out afterwards so that I don't accidentally promote temporary XAML changes into source control?
I thought about managing an entirely separate set of sln's and csproj's for WIP development but this is impossible for the same underlying reason based on the way those XAML namespace references (clr-namespace:) work. Also it is hard to do it as a team effort.
More info:
The reason I ask is because we have a number of projects with XAML resources (user controls, resource dictionaries, etc). Some of these get quite large because they are organized in a certain way that makes them a common place to put stuff (ie. all the combobox lookup - ALT-down - windows, or all common data templates, or what-not). Over time it becomes a problem because VS build operations take too long (impacts development efficiency). VS build operations get slower for larger projects:
a project with a centralized list of all data templates is likely to have a lot of things above it in the dependency stack, causing numerous other projects to be rebuilt after every change
any project with a central repository of anything will grow large and take a long time to compile (5 seconds /project is about my limit while I'm actively developing XAML, with a cap at 10 seconds to do the entire build operation and start debugging)
The biggest problem I have is with all the silly XAML namespace
references (clr-namespace:). They need updating so they will point to
the new home assemblies (assembly=)
Generally, ReSharper does great job, when refactorig xaml. It analyzes xaml files, and fixes wrong xml namespaces. However, you would need to go trough all the files, one by one.
You can also use just plain Find/Replace dialog and replace ;assemmly=TempProject with empty string. Write powershell script for that, if you need to do it more often.
And revert it back out afterwards so that I don't accidentally promote
temporary XAML changes into source control?
You just need to be carefull when doing check-ins, compare files with they original version and investigate changes
However, there is only one good solution for you. Split the projects into wpf usercontrol libraries. Not just for testing purposes, but permanently. Try to break your large resource files. Don't use practices like common place to put stuff when working on large projects. Consider using loosely coupled design and IoC (assembly injection instead of direct references) when possible. Create this shared assembly, which all other assemblies will reference. Don't create component that references lot of other components, but let the others inject themselves instead. Take a look at prism for an insipration: http://www.pluralsight.com/courses/prism-introduction
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.
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.
On a regular winforms solutions, how do you determine to break classes into different directories / namespaces or seperate projects. Besides binary dependencies should view, controllers, models all be in different projects ?
I tend to believe that you can happily work with a simpler system and separate your dependencies using folders. Adding extra projects makes the system slightly harder to work with, deploy and maintain as you now have several smaller things you have to coordinate.
Using folders you will still have to ensure that hasty developers do not bypass your layering, which can be a big concern with junior developers. You can watch out for violations using static checking (like NDepend) but no checker is perfect. If you have specific functionality at each level that you feel you need another protection level (internal) then by all means split it up into separate projects.
As for what folders to break them into I would likely follow the conventions found in web mvp/mvc frameworks such as.
Controllers\
Views\
Broken down by controller
Model\
You might want to read this blog post on the topic. Good luck.