How should I be organizing my SharePoint code? - c#

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 :)

Related

Multiple VS Projects in One Solution

I have a scenario that i have never come across and as such require help. I created an Visual Studio Web Application. The solution had two parts.
Project that holds all the UIs and
a Model that contain my c# code.
The objective was to achieve a 3 tier architecture. The model being the middle tier. The project is running and everything is awesome. NOW! This is my situation and I dont have an idea on how to approach it. I have to build another application, which basically is an extension of the first one. So how I went about starting this was to add another WEB Project to my currently solution. This had a lot of problem. When I deploy the project two web pages would load (one from each project). What i want is ONE webpage to load and base on your userId it will send you to the appropriate location. What I also saw was the second web project i added needed it's own users. How it should be is.. one set of users each having specific access to the application (which ever part). I need input on how to go about getting this done.
What I want is to debug 1 solution (with the 2 parts/projects). Base on userId he/she has access to a specific project but there is one user list that governs the entire solution and not two list, one for each project.
Is there a problem just adding pages to a directory in the existing web project? Normally, separate projects would be deployed as separate applications, not as merged into the same application. You can control access using web.config files in the "secured" directories
Another Architectural suggestion would be to create a Main web project that was sort of a wrapper if these applications are extensive enough and functionally dissimilar enough to warrant separate projects. This would be where your routing logic would take place and would provide simple stub directories for your paths (user-type 1 ... user-type n). Then you can create a project for each of your end paths and set some build actions that take the output of the sub projects and copy them to the output directories for the wrapper project, but this gets pretty complex.
I would still recommend keeping this as a single project if it is to be deployed as a single web application.
While it's possible to make this work as two separate systems, it's really a lot more headache than it's worth in most cases.
The question you should ask yourself is, is it really worth it to do this? What are you gaining from it?
This article explains how to do this:
http://support.microsoft.com/kb/307467
Another option is to create sub-sites, which is to add your additional project as a child. This is described here:
http://abhighag.blogspot.com/2012/03/separate-web-application-into-multiple.html

c# how to organize dll tools?

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

How can I structure an ASP.NET project for re-use

I am in the process of designing a web application which will have multiple installable modules that provide different functionality. There's a lot of common stuff going on here and I have 3 C# class libraries that I know will be easy to use on different projects.
The bit I am stuck on is the actual website itself. Ideally I'd like to make an ASP.NET page library that can be re-used over multiple projects but I understand that this is not possible.
How do you guys structure your website projects so that pages can be re-used across multiple projects? So far the only solution I've come up with is to create a repository in SVN and have it referenced in the svn:externals properties of the main project. This allows me to add pages to that directory that are common to all websites, and I know I will be able to use this to check them out to other projects. However, I feel this is a bit clunky and will cause problems when creating new projects (there'd be a number of steps to creating the new solution, ensuring that the right externals are in place).
Is there a better solution? What is the best way when you want to share common ASPX files across multiple client projects? How do you manage changes against them?
Thanks in advance!
EDIT:
Many thanks to David for his response. I've had more thought on this and thought I'd list some of my more concrete ideas/concerns. Firstly, a bit more about the project(s). Primarily, it's a CMS. However, we also have clients that will want CRM, and there's also clients that want neither and want an entire bespoke system from the ground up.
In my original post above, I spoke about having subdirectories of the main root (e.g, cms), using svn:externals to allow easy re-sharing of web pages across multiple projects. I am beginning to think this is the only way to do this. One thing that bothered me was if the client's url was:
http://www.shotgunanddribble.com/cms/content.aspx
However, I think I can use the Application_BeginRequest to mitigate horrible urls by rewriting them according to the configuration of the client's site. E.g, if a customer was just a CMS I could rewrite their Top-level-domain to /cms/. Same with if they were a CRM. If they were both:
http://www.shotgunanddribble.com/ -> /cms/
http://crm.shotgunanddribble.com/ -> /crm/
Is there any downside to using these kinds of rewrites? I think that, unless anyone else has any magical ideas, svn:externals is my only hope.
The actual code is easy enough to put in other assemblies and inherit from, but the ASPX files are definitely a different story. How about a common library of user controls to contain most of the display content, and each project would have its own pages which mostly just frame the user controls? I've never tried it, so there may be some "gotcha" that I'm just not picturing right now.

When do you decide to split up large projects into smaller projects?

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.

Namespaces combined with TFS / Source Control explanation

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.

Categories

Resources