C# Project Standard Directory Layout - c#

The java build tool "maven" has a standard directory layout for projects. What is the equivalent type of directory layout for a C# project? I'm just learning C# and .NET and it seems that the IDE just dumps everything into one directory, heh. Does C#/.NET follow a convention for the directory structure?
EDIT: This would be for a desktop application (windows forms or wpf). I'm looking at one of these two, but I don't know enough yet to really know which one. Ultimately I would like to learn both.

In C# directory layout should be strictly related to the namespaces you have. Each directory creates subnamespace. Here you may find instructions how to name namespaces properly.
If you use FxCop, it will inform you if your directory (namespace) layout is OK. The main rule is that there shouldn't be namespaces with a few classes/interfaces (FxCop suggests merging two namespaces into one in such a situation).
I think that's all I can say without knowing of some special project type (Uwe mentioned some of them in his comment) you have in mind.

Usually you get the following structure in your project :
/bin/Debug (after a DEBUG build)
/bin/Release (after a Release build)
/obj/Debug
/obj/Release
/Properties (contains AssemblyInfo.cs + Resource files when added via the assembly's properties)
/ServiceReferences (contains service references if any are present in your assembly)
In addition to the above, any solution folders you create (via r-click solution explorer -> add new / folder) will be present in your project's folder.
Does this help?

Related

Treat NESTED sub-projects in folders as child folders in IIS website in IntelliSense (ie. inherit web.config from root project)

There is a large ASP.NET web project, made up of many tens of thousands of files developed over the years.
The effective hierarchy looks as:
Site\All.sln
Site\root.csproj
Site\web.config
...
Site\Sub1\sub1.csproj
Site\Sub1\web.config <-- inherits from Site\web.config at runtime;
tell IntelliSense to do the same
Site\Sub1\page.aspx
...
Site\Sub1\Sub1a\sub1a.csproj
...
Site\Sub2\sub2.csproj
...
Site\bin <-- all assemblies compiled to here
The back-end code compiles fine and the project runs page.aspx without errors, as when executed IIS understands the nested web.configs (ie. Site\web.config is the root config and Site\Sub1\web.config inherits from the root config).
However, when editing page.aspx (as part of the Sub1 project) in Visual Studio 2022, IntelliSense is reporting errors (ie. 'assembly not referenced') because it does not understand Site\Sub1\web.config is a child web configuration that will inherit from the parent web.config.
There are other issue as well, such as not seeing/understanding the <system.codedom> (root web.config change to enable Roslyn) and/or that Site\bin is where the assemblies will be loaded from (which break aspx editor highlighting when non-SN shared assemblies are added to <assemblies>).
Without moving all the projects into the top-level folder:
Is it possible to get Visual Studio to apply the web.config as though it was actually running?
Similarly, is it possible to get Visual Studio to understand 'Sub1/Page.aspx' (not 'Page.aspx') is the relative path when the site is deployed?
A significant reason to not moving all the project files to the root folder, besides a fair bit of tedious semi-automated effort, is that it is very hard for VS to handle a 'show all files' in such a scenario. It is also painful (slow and management issue) to negate paths in SDK-style projects.
Right-click the project and select the pre-build event/post-build event command line dialog box in the project properties.
You can use any of these macros to specify locations for files, or to get the actual name of the input file in the case of multiple selections. These macros are not case-sensitive.
https://learn.microsoft.com/en-us/visualstudio/ide/reference/pre-build-event-post-build-event-command-line-dialog-box?view=vs-2022#macros

How to manually add a library to a visual studio 2017 project?

My apologies for this very basic question that has assuredly been asked and answered before, also for my very dated terminology. I searched for an answer, but failed to find anything helpful. I am using the latest update of VS 2017 Community, and I'm trying to manually add what I used to call a "function library" to a project, which sits under a "solution".
The project is simply a C++ or C# console application. What I have is a .h (header) file, a .lib (static library) file, and a .dll (dynamic library) file. I intend to make "function calls" to this library. I'm aware that I need to have my dll in the debug folder where the executable resides, but I'm not sure how to "add dependencies" in VS 2017. I know how to manage and install NuGet packages, but these files aren't a handy-dandy NuGet package.
I hope to get advice on doing this the right (VS 2017) way.
What I do in a situation like this is to create a folder, I use C:\Etc\SDKs\<name_of_library> and then within that folder create an include subfolder, and a lib subfolder. Note that the top level folder choice is completely arbitrary, place it where it makes the most sense to you.
In the C/C++ section of project properties on the General tab, or the corresponding section for C# projects, there's an entry for Additional include directories. Add the path to your newly created include folder there. That'll let you include the header file and have it work right.
In the Linker section of project properties, also on its General tab, there's a corresponding entry for Additional library directories. Add the path to your lib folder there. On the next tab down: Input there's an entry for Additional Dependencies. Add the actual name of the library file there.
Those steps should allow your project to be built using the .h, .lib and .dll files you have.
-- Edit to address comments --
The .lib file does go in the ...\lib folder, and the .h file in the ...\include, that's correct. However, you had the location of the .dll correct in your original question. That needs to be somewhere on the search path that the executable will find, so the easiest place is the same folder as the executable.
General tab is a poor choice of words on my part. General section might have been better here. When looking at the project properties, the left most pane is a tree view of the various property sections. With everything closed up, except the very top item open, you'll see
Configuration Properties
General
Debugging
VC Directories
> C/C++
> Linker
...
If you then double click on C/C++ it'll open up, and show the sections specific to the C/C++ compiler:
Configuration Properties
General
Debugging
VC Directories
V C/C++
General <<<<<
Optimization
Preprocessor
...
> Linker
...
If you click on the word `General that I've highlighted, that'll get you to the General section / tab I was talking about.
Likewise, double clicking the word Linker will open up that section, and under that you'll find the Linker General and Input sections.
Let me know if this still isn't clear, and I'll try to clarify.

Project management (sort of)

We have a big project(solution) with several smaller projects using some common assemblies (no GAC). Every time a project is changed and has to be tested, all files in the solution must be deployed in a testing location, separate from the main branch.
I would like to deploy only the files that have changed and use the ones not changed from the main branch. Something like this:
[MainBranchFolder]
File1.dll
File2.dll
File3.dll
.....
[Branch1 subfolder]
File2.dll
So, Branch1 contains only File2.dll. When the programs runs, it will look for any dlls in current folder and, if not found, will look into Parent folder.
I know a solution for this problem that requires some code changes but I wonder if something like this can be achieved using configuration only
[Edit] I see several ppl suggested some source code management. However this is not a source code issue, it's a binary code issue. MainBranch in my example is not source code, is a folder with all the compiled assemblies (exe and dll) in my projects
It sounds like you could use some Software Configuration Management (SCM)!
There are many choices out there and a quick Google search will reveal plenty. My preference is definately GIT.
Check out: http://git-scm.com/
with the Team Foundataion Server, you can do that with the customized build.
All of the responses seem to have a Code Versioning theme, which I'm seeing is not what you're looking for.
I ran into a different, but potentially similar situation:
3 Applications, each requires the same librar(ies).
Publishing the primary application requires the other 2 to be updated.
GAC was not an option (don't ask!)
Solution 1: I know where it is, just give me the damn thing!
(Which also let me store all kinds of useful common settings dictated by the master installed program.)
My solution was to maintain a known registry key:
Part 1: The registry Entry
HKLM\Software\FoobarInternational\CommonLibrary1 [String]
In CommonLibrary1 I stored the path to the common DLL's.
Part 2: The common "find my dll" library
Think plugin architecture - it looks in current dir for dll, and if fails, checks the the provided registry key for correct location.
Solution 2: Taking a walk
In a similar manner to solution 1, the library starts in its current directory, looks for the DLL, and if its not found, checks 1 directory higher.
Here are a few links to help you with each:
Getting the Parent Directory
Using the assembly once you find it
Talking to the registry
If you want the current directory of the code running (note: if the code is in a separate dll, you will get the location of THAT dll!)
Assembly.GetExecutingAssembly().Location
OR depending on what you need . .
string directoryName = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName;

How can I share common style information (css, images, etc.) across MVC sites?

It's dead simple to share functionality across multiple MVC projects. You just put the code into its own project and reference it in as many solutions as your heart desires. Clean, standard, glorious.
Is there any means to do this for styling code? I'd like to have our common CSS files, the ones that give our applications a similar look and feel, in just one place. Right now I have to spawn new copies for every new application. Thus if something needs to be fixed, it needs to be fixed a dozen times in a dozen places.
Has anyone else dealt with this? I can't separate out the CSS files into their own project, nor do I really want to have a web application that's just css sitting somewhere so all of the applications can use the files remotely via fully-qualified Urls. Is there a TFS trick you can do with source control to link the files together? Is there something I haven't thought of?
Here is the "dead simple" solution for sharing web resources between projects without using CDN, LESS, SASS, NuGet, etc:
Create common Solution Folders containing the resources to be shared, or simply designate one of the projects to be the master.
Use "Add as Link" to add the shared resource files to each project as needed.
Add an AfterBuild task to each project file that will copy the linked files to project folders. This is only needed so that Visual Studio test/debug (F5) will work locally.
If you need the details on how to do this, keep reading.
Configuring Solution Folders for the Shared Resources
** Note that if you're simply going to share files directly from one project to one or more additional projects then you can skip this step.
Visual Studio solution folders do not have to reflect physical file system folders, but doing so will help preserve your sanity. So first create the folders on your local file system and copy the resource files into them. The new folders should be located under your solution folder. For example:
\MySolution
\Common
\Images
\Scripts
\Styles
Back in Visual Studio, right click on the Solution Items folder and use Add Solution Folder to replicate the new file system folders.
Next, add the files to the new solution folders by right-clicking each folder and using Add Existing Item to add the contents of the folders.
Add Shared Resources as Links
For each project that will use the shared resources, right-click the project folder and choose Add Existing Item. Browse to the common folder, select the desired files, click the drop-down arrow next to the "Add" button and choose "Add as Link".
You may get a source control warning about adding files that are outside of the project directory structure, but this can be ignored since the linked file will be under source control at its source.
Add an AfterBuild Task to Copy Files
When you publish the application to a server the linked files will copied to the project folders to which they are linked and everything works as expected. However, in the development environment the linked files do not physically reside in the project folders. So when you hit F5 to test your application in VS, the shared resources will be missing.
The simple solution is to add an MSBuild task to copy the linked files from their source after each build. This needs to be done to for each project that contains the shared resource links.
Right-click the project and choose Unload Project. Right-click the project again and choose Edit <ProjectFileName>. Scroll to the bottom and add the following (just above "</Project>"):
<Target Name="AfterBuild">
<!-- Copy linked content files to local folders so that they are available in the debugger.
This is only an issue when running the application locally. The linked files should
be automatically published to the correct folder when publishing to a web server. -->
<Copy SourceFiles="%(Content.Identity)"
DestinationFiles="%(Content.Link)"
SkipUnchangedFiles='true'
OverwriteReadOnlyFiles='true'
Condition="'%(Content.Link)' != ''" />
</Target>
** Copy task adapted from this link in TheCodeDestroyer's answer.
Save the project file then right-click and choose Reload Project.
Why not just have one site host that base styling and the other sites reference those styles? I don't see anything wrong with this.
You could create a CDN application of sorts to do this, too.
MVC App #1
<link src="~/css/styles.css" />
MVC App #2
<link src="http://mvcapp1.com/css/styles.css" />
Well, I don't know much about asp.net development, so forgive me, if it's not the case, but
If resource files in your project have Build Action set to None or Content and Copy to Output Directory set to Copy..., you can easily create the Class Library type of project and place all the files there (preserving the paths), and then reference this "Class Library" in every project that needs the files. Every file will be copied to every referencing project on solution build.
For Embedded Resource build action it will also work, but, you'll need to find a way to specify the assembly, which contains these files (because it will differ from Assembly.GetEntryAssembly).
Personally I don't like or want the CDN solution as if you have many pages they depend on CDNs 100% up time. After some research I found this solution which was perfect for my use I hope whoever will look for an alternative this is one of them:
http://mattperdeck.com/post/Copying-linked-content-files-at-each-build-using-MSBuild.aspx
1 - Look into CSS template systems as mentioned :
SASS-Lang
Less
http://css-tricks.com/sass-vs-less/ (really good article to start, many related items to in his related posts widget)
These allow you to code your stylesheets in organised manners. You can quickly add dynamic configurations and global changes easily.
2 - Developer your own CSS global listing system :
If you prefer not to use the above CSS stylesheet system. Example
//cdn.com/assets/css/reset.css
//cdn.com/assets/css/main.css
//cdn.com/assets/css/page_home.css
//cdn.com/assets/css/page_cart.css
even...
//cdn.com/assets/global/form_styles.css
//cdn.com/assets/global/global_shortcuts.css
In these, the same form padding, table and tr and other padding rules. Example
.black{color:#000 !important}
.right{float:right}
.left{float:left}
I know I sound like framework mentality but it works..
You can quickly alter the global to ensure all pages are updated.
The CDN storage and compass suggestions are valid too. You see storing on a CDN will save the headache of worrying about application failure / speed / load.
Your application can simply be like
/cloud/servers/settings/global/db
/cloud/servers/settings/global/librarys
/cloud/servers/settings/global/css_config.php (example)
/cloud/servers/1/webapp.com/
/cloud/servers/1/webapp.com/model
/cloud/servers/1/webapp.com/view
/cloud/servers/1/webapp.com/view/themes/tpl
/cloud/servers/1/webapp.com/inc
/cloud/servers/1/webapp2.com/
/cloud/servers/1/webapp2.com/model
/cloud/servers/1/webapp2.com/view
/cloud/servers/1/webapp2.com/view/themes/tpl
/cloud/servers/1/webapp2.com/inc
//cdn.com/assets/css
3 - Configuration of Approach
I personally think that the question should be about the approach of your overall development methodology. Having CSS sit on a CDN application, or having a CSS on a separate server which syncs to the CDN for production live mode is a good idea - keeping it separate and maintaining it via a stylesheet language is even better. You can then quickly use skins, css libraries, image libraries and more. Keeps things organised, faster and much better and ENJOYABLE to look at and take pride in coding with.
Keeping it and using a better system is what is needed. You should use manual and the classical approach of a folder structure IMO. You won't have to worry about responsive application design for mobile/tablet and other bearing issues with updating one CSS line for all the apps or even single apps - even languages, and dealing with multi site development teams.
JUST MY HUMBLE OPINION
Would also strongly recommend a CSS stylesheet language, sure many people hate them. But they are becoming quite useful, especially SAAS it's not a hype like NodeJS was.. it actually works. And does wonders. Look at TopShop, GorgeousCouture.. Arcadia sites.. multiple languages, multiple currencies.. servers and teams working on the same cross brand and several applications for each store..
We had the same problem and for our purposes we put all general CSS/JS/Images/Layout View into NuGet package and reuse it from every application where we need it. It perfectly works for us.
If you're open to using Sass, Compass extensions might be just what you need.
http://compass-style.org/help/tutorials/extensions/
An extension, when bundled as a gem, allows you to easily include the styles contained within the gem from anywhere on the system that has the gem installed. I recently used this in my latest application (a specialized multi-user CMS where each user has their own subdomain that has a customized layout, but all of the components/widgets have the same styling throughout the application). Setting up a new subdomain's styling is as simple as running a single command and customizing the template I've setup that has a skeleton of a simple layout.
Compass extensions can be used to hold images and JavaScript files as part of a template, but deployed files aren't automatically updated like the styles are (templates from a Compass extension differ from the stylesheets, as the templates are for copying and the stylesheets are for importing).

Visual Studio (C#) Build Output path using environmental variables

Is it possible to use environmental variables in the build output path in VS 2008 (et al)/ I'm trying to find a solution where several developers on my team using both Windows XP & 7 and all with different Windows logons, can all modify projects and common referenced dll's (source held on Source Safe) and not screw up the relative paths? I've tried such things as %userprofile% and $(userprofile).
I've looked into post build events but these do not really seem to provide an anawer to my problem. Sadly I'm not in the position to use 3rd party add-ons either as these will be non-commercial and it's nearly impossible to get authorization for any licences for them.
(Similar unanswered question at Output path for build in visual studio 2010)
You need to open the csproj file in a text editor and manually enter your environment variables in the OutputPath section. Visual Studio escapes the '$', '(' and ')' when you try to do this from the IDE.
I've used the subst command to accomplish this sort of thing in the past. Essentially all project references define paths in relation to a known drive letter like R:\MyProject\outputs.
Then every developer can map the R: drive (or whatever) to the folder structure particular to their environment. As long as the folder structure beneath the mapped drive is the same, the location of that mapped folder can vary between machines, builds, and users.
This works well as developers can then set up their environment with a simple batch file and easily switch between branches, projects etc and relative pathing within the projects is not broken.
PaulTee,
Is it a longshot to ask you try directory replication? Like Dropbox/Synctoy and other tools that invokes a file-copy from choosen location to the expected shared location?
In your situation, I would love to use the built-in environment variables. Probably there are a way to make it work, but until then i would go for such a solution. I would also have in mind that different users compiling to same directory, would make conflicts with both file versions and file locks (used by other user).
If you don't mind the extra copies, you could add post-build event that copies the project outputs to a commonly-agreed location for shared dlls, and everyone uses a non-relative reference to that location. It would still, though, require standardization of that target location, so maybe it is not what you are looking for. (example below would allow for drive letter independence at least)
copy $(TargetPath) \dependencies
While I don't quite understand what you're asking for, it sounds like symlinked directories will help -- you can configure the solution to output to some folder that will be symlinked to arbitrary locations on each individual box.
http://en.wikipedia.org/wiki/NTFS_symbolic_link
ghost edit - mklink is apparently new in 7, but older versions still support it (Russinovich to the rescue once again):
http://technet.microsoft.com/en-us/sysinternals/bb896768

Categories

Resources