As an ISV company we slowly run into the "structure your code"-issue. We mainly develop using Visual Studio 2008 and 2010 RC. Languages c# and vb.net. We have our own Team Foundation Server and of course we use Source Control.
When we started developing based on the .NET Framework, we also begun using Namespaces in a primitive way. With the time we 'became more mature', i mean we learned to use the namespaces and we structured the code more and more, but only in the solution scope.
Now we have about 100 different projects and solutions in our Source Safe. We realized that many of our own classes are coded very redundant, i mean, a Write2Log, GetExtensionFromFilename or similar Function can be found between one and 20 times in all these projects and solutions.
So my idea is:
Creating one single kind of root folder in Source Control and start an own namespace-hierarchy-structure below this root, let's name it CompanyName.
A Write2Log class would then be found in CompanyName.System.Logging.
Whenever we create a new solution or project and we need a log function, we will 'namespace' that solution and place it accordingly somewhere below the CompanyName root folder. To have the logging functionality we then import (add) the existing project to the
solution.
Those 20+ projects/solutions with the write2log class can then be maintained in one single place.
To my questions:
- is that a good idea, the philosophy of namespaces and source control?
- There must be a good book explaining the Namespaces combined with Source Control, yes? any hints/directions/tips?
- how do you manage your 50+ projects?
Here's how we do it (we're also an ISV, and we use TFS):
We have an in-house framework that all of our products use. The framework includes base classes for our Data Access Layer, services like logging, utility features, UI controls, etc).
So, we have a Team Project for our framework:
Framework\v1.0\Main\Framework
(note the repetition of "framework", looks weird, but it's important)
Then we have a Team Project for each product, and we branch the framwork into the team project:
ProductName\v1.0\Main\ProductName
ProductName\v1.0\Main\Framework (branched from \Framework\v1.0\main\Framework, we make this branch read-only)
any code under "\Main\ProductName" can reference any code under\Main\Framework
Further, if we need to create working branches of our product, we just branch at "Main" like so:
ProductName\v1.0\WIP\MyBranch\ (branched from Main, where MyBranch == Main)
That gives us 2 really cool features:
I can create branches without messing up my references as long as I keep everything below "Main" together. This is because VS will use relative paths to the references, and as long as I keep everything below Main together (and I do NOT reference anything "above" main, the relative paths remain intact.
If I update the "real" framework (under \Framework\v1.0)), I can choose for each product when I want to merge those framework updates into the product's code base.
(that's really useful if you use shared libraries, because it decouples internal releases of your shared framework from external releases of your products). If you are just moving to shared libraries, one of the problems you are going to encounter is "collisions", where a change to your shared code mandates changes to your product code in order to stay compatible. By branching your shared code, you can update your framework without immediately impacting all of your products at the same time.
Related
I've been trying to find some clear documentation on best practices with regard to nesting Visual Studio solutions. Please bear with me if the terminology is wrong - I'm not really experienced in creating significant solutions.
Here's what I'm trying to achieve.
I have a website that is a web application in VS speak - so it is my solution.
The site will have some reusable functionality. Normally I would just create a class library project and have done with it.
However, in this case the functionality is database driven via Entity Framework. If I was creating a self contained project, I would create a new solution, containing 3 library class projects for BLL, DAL and Entities.
So instead, I'm thinking a second solution containing the 3 class libraries - obviously I don't need a second front end as the primary web application will do the job.
So, I have a number of options as far as I can see:
Create a new solution as described above that can be plugged into my
main solution - but what do I do with the unwanted project that
contains the App_Data, Account folders etc?
Create a single class library and create visual separation through
folders.
Create 3 separate class lib projects (although this gives least
benefit)
Or, something else I'm not aware of.
Sorry if this sounds basic to you guys that do this day in day out, but I just don't have the necessary experience to make the right call.
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 would like to know which is the best way to organize the dll tools.
For example, I can have a project that has all the class tools the the company has been implement. For example, class to work with strings, class to work with files... and so on. I mean, a generic dll with tools that I can use in many projects. This would be a generic myCompaty.Utils.dll for example.
Other way it to have many dlls, of for each type of work. For example, I could have a myCompany.Utils.Files, other myCompany.Utils.Strings... etc.
With the first option, I would have only one dll, but if two persons need to add or fix something, only can work one person, because if two persons work at the same time, when one of the person compiles the new dll, the other person loses the work.
If I have many dlls, one for each kind of type of work, then is more difficult that two persons need to modify the same dll, because it's possible that each person is responsible of one of the dlls. However, the problem is that in this way, when I deploy the application, I would have a lot of dlls in the program directory.
So I would like to know which is the best practice when is created dlls.
Thanks.
From your question it is clear that you are using no versioning system. Try checking out something like Tortoise SVN - then, you will have no problems with several people working on same piece of software.
Regarding DLLs - I would go with having multiple DLLs, each only containing a specific type of utility methods. It will make deployment simpler. If you would do the opposite, that is, have a single DLL for all your utility methods, you would need to redeploy it everytime anything in it changes - you change the code responsible for working with files, you have to ship the whole DLL that will contain unrelated code, too. Whereas if you'll have multiple DLLs, you only need to redeploy the one that has really changed.
Basically it's going to depend on the number of classes, interfaces and delegates that your library is going to own.
Imagine the case you've 3000 classes in your "Company.Shared.dll" and you're developing a Web application. 600 of 3000 classes are for mobile development. What's the chance of using them in your Web application development? Zero.
So why you'd be deploying a 3000-classes-assembly for a Web application development if you only need Web development-related classes? Library size is greater than a Web-specific one as first can contain code for a lot of things which wouldn't be working in Web development.
For that reason you'd have a shared library called Company.Shared.Web.dll and a common to all development scenarios called Company.Shared.dll.
You can use above logic for other cases and scenarios.
Apart from the versioning system, (should be a must when more than half developer works on a project), it's really crazy that your organization allows everyone to change the base library (or libraries) on which every other project depends on. This will be evolve in a mess very quickly.
In my shop only one/two people are allowed to change anything there. And these guys are the most skilled and valuable colleagues.
For the subdivision of functionality present in the library I am not concerned with the big one DLL. It's true that I need to redistribute all even when we change a little bit of code (and when your code is mature and well tested this happens very rarely), but keeping track of every dll shipped for this project or for that project outweights the cost of the single one DLL
Over time, the code base I maintain has grown exponentially. We have a variety of different utility classes, webparts, event receivers, console applications, and more.
Typically, each webpart lives in a separate DLL (one solution and one project per web part). Our utility classes have also been largely separated out into their own separate DLLs (this includes any specialized list access classes that get grouped with their beans together in a DLL). This has led to a large amount of solutions which has become more difficult to maintain (upgrading each solution to Visual Studio 2008, or simply just trying to find out the maze of DLL references).
With my discovery of the SharePoint Guidance, I'm re-evaluating our current code structure. For example, it looks like they recommend combining all of your specialized list access classes into a Repository (we've done completely the opposite so far by splitting them into DLLs based on what "solution" the code is for).
Questions: How should I be organizing my code? How do you decide what goes into a solution vs project vs folder or what goes in a namespace? One solution per web part?
I usually organize my code by functionality. Let's say I've got an extranet project and some code for some intranet webparts, I seperate it out into a Extranet and an Intranet project, and seperate the different classes of code (eventreceivers, timerjobs, webparts, etc.) into different namespace.
That way, I can deploy (sub)sets of functionality to different farms if I want to, and when editing code I got everything that depends on one another in the same place :)
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.