views:

434

answers:

5

This is one of those things that is so simple that no one ever just comes out and says it in any of the tutorials I've read.

I've been creating a few stand alone .NET applications as well as a few DLL based plug-ins for other programs. I've noticed that a project in Visual Studio, at least with Windows applications and class libraries, compile into a single file (EXE or DLL).

Is this always the case? In terms of organizing a larger application should I always think of projects in Visual Studio as corresponding to a single file in the final program?

+2  A: 

For Visual Studio, yes. Search the Internet for "netmodule" and you'll find the documentation you're looking for. I happened to come across them today as we were looking to assemble multiple projects into a single DLL.

MSDN: http://msdn.microsoft.com/en-us/library/226t7yxe(VS.80).aspx

No Refunds No Returns
+1  A: 

Each project does compile to a single file. (Except for web site projects)

However, if you set the Build Action for any file in the project to Copy Always or Copy if Newer, the project will copy that file to the output folder.
Also, if an EXE project has an App.config file, it will also be copied to the output folder.

If your project references a DLL (whether your own or someone else's) that isn't part of the core framework, it will copy that DLL to the project's output folder, resulting in two files (although only one of them will contain the code from the project itself)

Also, in addition to DLLs and EXEs, Visual Studio will also create a .pdb file containing debug symbols in the output folder. This file is used by the debugger and must not be distributed to your users. (Unless you want them to debug your code for you)

SLaks
+1  A: 

Not necessarily. If your project has culture oriented resources, they are typically compiled into separate assemblies (dlls). Also ASP.Net projects do not get compiled into a single assembly, you will always have either your aspx/ascx files or their marker equivalents left separate to the compiled code.

slugster
_Web Site Projects_ don't get compiled into a single assembly - they don't get compiled at all. _Web Application Projects_ _do_ get compiled into a single assembly.
John Saunders
Good point - all the web stuff i do is a web app project, so i forgot all about mentioning the difference :)
slugster
If you use Web Deployment projects, you can still compile them into a single assembly. Aspnet_merge.exe performs the magic.
Lex Li
+3  A: 

For your simple projects, yes, you'll always get one assembly per project. However, if you move towards more production ready software the answer is different. Let's say you want to deliver a DLL, but it contains text which must be displayed to a user. You probably want to localize that text (provide English and German versions or even US-English and Great Britain-English [think program vs. programme]). You'll place your text into resources and then compile those resources into what are called satellite assemblies. You'll get one satellite assembly for each locale which you choose to support.

Here's a quick run down on how to generate and use satellite assemblies: http://sanjaysainitech.blogspot.com/2007/08/satellite-assemblies.html

I see people talking about netmodules and ILMerge. I think that if you're worrying about netmodules then you're doing something wrong because you're not using the tools Microsoft gave you (or you're over in Mono land in which case you don't any tools from Microsoft). I haven't used ILMerge, but after reading about it I'm not sure I trust it. This person says it works fine except for WPF/XAML code; this person had trouble accessing embedded resources after running ILMerge; this person saw optimized code that couldn't be stepped though using a debugger after running ILMerge. That's enough information to tell me that ILMerge is not a production ready tool for all scenarios. Part of designing software is figuring out how you'll deploy it. If you want to deploy a smaller number of assemblies, you should design your software that way rather than mucking about in the IL after you've compiled it. As cartographers used to say, "Here be dragons."

Mike Post
+3  A: 

Example how to create several modules and link theme into a single dll:

csc /t:module RarelyUsedTypes.cs
csc /out:AllTypes.dll /t:library /addmodule:RarelyUsedTypes.netmodule AllTypes.cs

For more information see Richter's book CLR via C#.

You can automate this process for Visual Studio.

For each of your projects create a netmodule or an assembly and compile/merge them all into a single assembly.

First alternative. This was proposed by Jay R. Wren:

This is a cute hack, but with the CSC and VBC both supporting the /target:module and /addmodule options, you could actually do this without ILMerge just by using a shell script or make file.

Visual Studio doesn't support the "netmodule" type, but MSBuild does.

Add the VB project to your solution. Unload the project and edit the project file.

Change OutputType to module : module

Instead of adding a reference to the desired project, we add a module. Sadly, again VStudio fails here, but MSBUILD works just fine. Unload the project and edit the project file. Add an item group with AddModules include directives.

This will tell msbuild to tell CSC to use /addmodule directives, just like the Reference Item Group which Studio does manage.

Major Drawback: No Visual Studio Intellisense for the added module. We already have references, it is too bad we don't have modules.

SharpDevelop has the first step, but the second step, an "Add Module" gui has been open as a low priority item since SD 2.0.

Second way. This great article (by Skott Hanselman) describes how to megre assemblies automatically if you're using Visual Studio. It does give you IntelliSense support, unlike the first alternative.

Roman Boiko
All three ways produce a single assembly. But only the third way gives you a single **file**.
Roman Boiko