Assemblies are the fundamental building blocks of a .NET Framework application. They contain the types and resources that make up an application and describe those contained types to the common language runtime. Assemblies enable code reuse, version control, security, and deployment.

Put simply, an assembly is a project that compiles to an EXE or a DLL file. Although .NET EXE and DLL files resemble their predecessors externally, the internal structure of an assembly is quite different from that of an EXE or DLL created with earlier development tools. An assembly consists of four internal parts:

The assembly manifest, or metadata. This contains information about the assembly that the common language runtime uses to obtain information about the assembly.
The type metadata, which exposes information about the types contained within the assembly.

The intermediate language code for your assembly.

Resource files, which are nonexecutable bits of data, such as strings or images for a specific culture.

The assembly manifest contains the metadata that describes the assembly to the common language runtime. The common language runtime then uses the information in the assembly manifest to make decisions about the assembly's execution. An assembly manifest contains the following information:


It contains the name and version number of the assembly, and can contain optional information such as locale and signature information.
Types and resources. It contains a list of all the types that will be exposed to the common language runtime as well as information about how those types can be accessed.


It contains a list of all files in the assembly as well as dependency information for those files.

Security permissions

The manifest describes the security permissions required by the assembly. If the permissions required conflict with the local security policy, the assembly will fail to execute.

For the most part, the developer does not have to be concerned with the contents of the assembly manifest. It is compiled and presented to the common language runtime automatically. The developer does, however, need to explicitly set the metadata that describes the identity of the assembly.

The identity of the assembly is contained in the AssemblyInfo.vb or .cs file for your project. You can set identity information for your assembly by right-clicking the AssemblyInfo icon and choosing View Code from the drop-down menu. The code window will open to the AssemblyInfo code page, which contains default null values for several assembly identity attributes. The following code example shows an excerpt from the AssemblyInfo file.

Creating Class Library Assemblies

You will frequently want to create class library assemblies. These represent sets of types that can be referenced and used in other assemblies. For example, you might have a custom control that you want to use in several applications or a component that exposes higher math functions.

Such an assembly is not executable itself, but rather must be referenced by an executable application to be used.

You can create class library assemblies and control library assemblies by using the templates provided by Microsoft Visual Studio .NET.

The class library template is designed to help you create an assembly of types that can be exposed to other applications, and the Microsoft Windows control library template is provided to assist you in building assemblies of custom controls.
  1. To create a class library assembly
  2. From the File menu, choose New, and then choose Project.
  3. The New Project window opens.
  4. In the New Project window, select Visual Basic Projects or Visual C# Projects as appropriate, and then choose Class Library or Windows Control Library as appropriate.
  5. Write the code for your class library or Windows control library.
  6. Set any required identity information in the AssemblyInfo file of your assembly.
  7. From the Build menu, choose Build to build your assembly.
Resources and Resource Assemblies

Most production-ready applications will use resources. Resources are nonexecutable data that is embedded in an application. Examples of resources might include strings that are displayed in the user interface based on the culture settings of the system or a set of images. Packaging such data into resource files allows you to change the data required by a program without recompiling the entire application.

In this section, you will learn to create resource files manually, how to embed these resource files into assemblies or create resource-only assemblies, and how to use code to retrieve code and objects stored in resource assemblies.

Creating Resource Files

The .NET Framework includes a sample application called ResEditor that can be used for creating text and image resource files. The ResEditor application is not integrated with Visual Studio .NET—it must be run separately. In fact, it is supplied as source code files and must be compiled before it can be used.

The ResEditor source files are located in the \FrameworkSDK\Samples\Tutorials\resourcesandlocalization\reseditor folder, which is in the folder that Visual Studio .NET is installed in. You can build the application using either the batch file supplied in that folder or by adding the source files to an empty Visual Studio project, configuring, and then building them.

To create a resource file with ResEditor

If necessary, compile the ResEditor source files. They can be found in the \FrameworkSDK\Samples\Tutorials\resourcesandlocalization\reseditor folder, which is in the folder that Visual Studio .NET is installed in.

Open ResEditor. If you want to edit a preexisting .resources or .resx file, you can open it by choosing File, Open, and then browsing to the appropriate file.

From the Add drop-down menu, choose the type of resource you want to add. In the Add text box, type the name that the resource will use. Click the Add button to add the resource to the file.

In the main pane, click the cell next to the resource name to specify the value. If the resource is a string, type the string into the box. If it is an image, browse to the correct file.

If you want to rename any of the resources, highlight the resource you want to rename by clicking it, type the new name in the rename text box, and click the Rename button to apply the new name. If you want to delete a resource, highlight the resource by clicking it and choose Delete from the Resources menu.

When you have finished editing your resource file, choose File and then Save As to save your file. You can save it as either a .resources file or a .resx file.

Once created, you can add .resources or .resx files to your project by selecting Project, Add Existing Item, and then browsing to the appropriate resource file.

Embedding Resources

Once you have created resource files, you can embed them in your assembly. This allows you to package resources into the same assembly as the code files, thus increasing the portability of your code and reducing its dependence on additional files. To embed an externally created resource into your assembly, all you have to do is add the file to your project. When the project is built, the resource file will be compiled into the assembly.

To embed resources in your assembly
  1. Create the resource file. This can be either a .resources file or a .resx file. You might find it useful to use a tool such as ResEditor.
  2. From the Project menu, choose Add Existing Item.
  3. The Add Existing Item window opens.
  4. Browse to the correct resource file, and click Open to select it.
  5. The file is added to your project.
  6. From the Build menu, choose Build to build your solution.
  7. The assembly is built with the resource file embedded.
Creating Resource Assemblies

You can create assemblies that only contain resources. You might find this useful in situations where you expect to have to update the data contained in resource files, but do not want to have to recompile your application to update it.

To create a resource assembly

From the File menu, choose New, and then choose Project.
The New Project window opens.

In the New Project window, choose Visual Basic Projects or Visual C# Projects as appropriate, and then choose Empty Project. Click OK to create the project.
A new empty project is created.

From the Project menu, use Add Existing Item to add your resource files to your project.
In Solution Explorer, right-click your project and choose Properties.
The Project Property Pages open.

In the Output Type drop-down menu, change the output type of your project to Class Library.
From the Build menu, choose Build .

Your resources are compiled in the assembly.

Creating Satellite Assemblies

When creating international applications, you might want to provide different sets of resources for different cultures. Satellite assemblies allow different sets of resources to automatically be loaded based on the CurrentUICulture setting of the thread. You learned how to automatically generate applications for localization in Chapter 8. In this section, you will learn how to create additional satellite assemblies and incorporate them into your application.

Visual Studio .NET allows you to effortlessly create satellite assemblies. All you need to do to create a satellite assembly is to incorporate alternate sets of resource files that are appropriately named into your application. Visual Studio .NET does the rest upon compilation.

To be incorporated into a satellite assembly, your resource file must follow a specific naming scheme based on the culture it is designed for. The name of a resource file for a specific culture is the same as the name of the resource file for the invariant culture, and the culture code is inserted between the base name and the extension. Thus, if we had a resource file named MyResources.resx, a resource file containing alternate resources for neutral German UIs would be named And a version of the file containing German resources specific for Luxembourg would be named

Once these alternate versions of the file are added to your solution, they will automatically be compiled by Visual Studio .NET into satellite assemblies, and a directory structure for them will be created. At run time, the culture-specific resources contained in these files will automatically be located by the common language runtime.

To create satellite assemblies

Create alternate versions of your resource files specific to locales where your application will be run.

Name your resource files correctly for their specific culture. Names for resource files for satellite assemblies must contain the culture code separated by periods between the base name and the extension. The base name and extension must be the same as the resource file for the invariant culture.

From the Project menu, use Add Exiting Item to add these files to your application.
From the Build menu, choose Build Solution to build your solution.

Culture-specific resource files are automatically compiled into satellite assemblies and placed in an appropriate directory structure.

Retrieving Resources at Run Time

At run time, you can use the ResourceManager class to retrieve embedded resources. A ResourceManager, as the name implies, manages access and retrieval of resources embedded in assemblies. Each instance of a ResourceManager is associated with an assembly that contains resources.

You can create a ResourceManager by specifying two parameters: the base name of the embedded resource file and the assembly in which that file is found. The new ResourceManager will be dedicated to the embedded resource file that you specify. The base name of the file is the name of the namespace that contains the file and the file without any extensions.

For example, a resource file named in a namespace called Namespace1 would have a base name of Namespace1.myResources.

The assembly parameter refers to the assembly that the resource file is located in. If the assembly that contains the resources is the same assembly that contains the object that is creating the ResourceManager, you can get a reference to the assembly from the type object of your object.

Understanding Private and Shared Assemblies

Most of the assemblies you create will be private assemblies. Private assemblies are the most trouble free for developers and are the kind of assembly created by default. A private assembly is an assembly that can be used by only one application. It is an integral part of the application, is packaged with the application, and is only available to that application. Because private assemblies are used by one application only, they do not have versioning or identity issues. Up to this point, you have only created private assemblies.

At this point, something might seem incongruous about that last paragraph. For example, you learned how to create custom controls in Chapter 7, and you can use the DLL that contains your custom controls in any number of projects. Yet, these are private assemblies. How can this be?

When you add a reference to a private assembly to your project, Visual Studio .NET creates a copy of the DLL containing that assembly and writes it to your project folder. Thus, multiple projects can reference the same DLL and use the types it contains, but each project has its own copy of the DLL and therefore has its own private assembly.

Only one copy of shared assemblies, on the other hand, is present per machine. Multiple applications can reference and use a shared assembly. You can share an assembly by installing it to the Global Assembly Cache. There are several reasons why you might want to install your assembly to the Global Assembly Cache. For example:

Shared location. If multiple applications need to access the same copy of an assembly, it should be shared.

Security. The Global Assembly Cache is located in the C:\WINNT (Microsoft Windows 2000) or WINDOWS (Microsoft Windows XP) folder, which is given the highest level of security by default.

Side-by-side versioning. You can install multiple versions of the same assembly to the Global Assembly Cache, and applications can locate and use the appropriate version.

For the most part, however, assemblies that you create should be private. You should only share an assembly when there is a valid reason to do so. Sharing an assembly and installing it to the Global Assembly Cache requires that your assembly be signed with a strong name.

Strong Naming

A strong name is a name that guarantees the identity of an assembly. It consists of information about the identity of the assembly, such as the name, version number, and culture information (if present), and the public key of a public/private key pair. This information is encrypted with the private key of the key pair and can be decrypted with the public key of the key pair. Because no one but the developer has access to the private key, the strong name cannot be replicated by anyone but the developer, thereby ensuring the identity of the assembly.












No comments:

Post a Comment