What's New in .NET 2.0 for Assemblies and Versioning? (Cont.) Friend Assemblies An interesting assembly-level attribute introduced by .NET 2.0 is the InternalsVisibleTo attribute, defined in the System.Runtime.CompilerServices namespace. The InternalsVisibleTo attribute allows you to expose internal types and methods to clients from another specified assembly. This is also known as declaring a friend assembly. For example, suppose the server assembly MyClassLibrary.dll defines the internal class MyInternalClass as. internal class MyInternalClass { public void MyPublicMethod() {...} internal void MyInternalMethod() {...} }
Suppose you add this line to the AssemblyInfo.cs file of MyClassLibrary.dll. [assembly: InternalsVisibleTo("MyClient")]
Now any client in the assembly MyClient.dll and MyClient.exe can use MyInternalClass and call its public or internal members. In addition, any sub class in the MyClient assembly can access members marked as protected internal. Declaring an assembly as a friend could easily be abused and violate the essential encapsulation of the internals of the assembly, and tightly couple the client to the internals of the server assembly. Declaring a friend assembly is available for when you break an existing assembly into one or more assemblies by moving some of the types to new assemblies. If the relocated types still rely on internal types in the original assembly, declaring a friend assembly is a quick (albeit potentially dirty) way of enabling the move. Another case where a friend assembly is handy is when you want to test internal components but the text client resides in different assembly. | " | The InternalsVisibleTo attribute allows you to expose internal types and methods to clients from another specified assembly.
| " |
When you apply the InternalsVisibleTo attribute like so: [assembly: InternalsVisibleTo("MyClient")]
It does not matter whether the MyClient assembly has a friendly name or a strong name in both cases it is allowed access to the internals of the server. Obviously this is not a very secure or safe way of exposing your internal types. Using the InternalsVisibleTo attribute should be restricted to assemblies developed in conjunction with the server assembly. All a third-party assembly has to do to access the server assembly internals is to change its friendly name. In addition, this use of the InternalsVisibleTo attribute is version indifference any version of the MyClient assembly can access the server internals. To provide the additional degree of security to the InternalsVisibleTo attribute, the server assembly can also specify the token of the public key of the client assembly. [assembly:InternalsVisibleTo( "MyClient,PublicKeyToken=745901a54f88909b")]
When specifying the public key token, the server assembly grants permission to access its internals only for client assemblies with a matching friendly and strong name, and the client-side compiler enforces that. In addition to the friendly name of the client assembly, the server assembly can specify a version number. [assembly:InternalsVisibleTo( "MyClient,Version=1.0.0.0")]
The effect of the version number depends on whether or not the client assembly has a strong name. If the client assembly has only a friendly name, then the version stipulation has no affect, and such clients can freely access the internals of the server assembly. If, however, the client does have a strong name (any strong name), then the client-side compiler will insist that only a client assembly with a matching strong name and version number can access the internals. Note that this behavior is akin to reverse-versioning, where the server constrains the version of its clients. Of course, the server assembly can specify both a version number and a public key token. [assembly:InternalsVisibleTo( "MyClient,Version=1.0.0.0, PublicKeyToken=745901a54f88909b")]
In which case, only clients with a matching strong name and version number can access the internals. Supplying Assembly Version Number In Visual Studio 2003, you had to manually write the various assembly-level attributes, including the version number. Visual Studio 2005 provides visual editing of all the attributes commonly found in the AssemblyInfo file. Visual Studio 2005 will even auto-populate certain values such as company name and copyright statements based on the information found in the Registry as part of Windows activation process. To specify the version number using Visual Studio 2005, bring up the assembly properties and open the Application tab. Next click the Assembly Information button to display the Assembly Information dialog (Figure 3).  Figure 3: Specify the assembly version in the Assembly Information dialog.Under Assembly Version you'll find four text boxes that you can use to specify the assembly version. The Assembly Information dialog is merely a visual editor for the set of assembly attributes found in AssemblyInfo. For example, the AssemblyVersion and its value corresponding to the settings in Figure 3 is: [assembly: AssemblyVersion("1.2.3.4")]
The Assembly Information dialog also lets you specify the file version number. The file version number has no bearing whatsoever on .NET versioning, and is simply available for your custom needs if you want to apply a proprietary semantic to it. | & | | Protecting Your Keys
The most secure way to protect your keys is to store them in a secure cryptographic container, the same container used for storing certificates. To do so, simply double-click on the .pfx file in the File Explorer. The Windows Shell extension will bring up the Certificate Import Wizard. Use the Wizard to specify the .pfx filename. After providing the password, you can select the level of protection for the key: you can enable exporting the key from the container, and enable prompting for password on every use of the key. Next, select the certificate store and finish the Wizard. You can also manage all your keys and certificates using the Certificates management console snap in. Type mmc in the Run prompt to get a clean management console. Select File, choose Add/Remove Snap-in..., then Add... in the Add/Remove Snap-in dialog box. Select Certificates, and add either the current user or computer account. You can now browse and manage your certificates and strong name keys. |