State Street Gang
.NET, straight up

C# 4.0

July 14, 2008 14:57 by will

I've just finished watching the "C# 4.0 Meet the Design Team" video, and here's what I've learned:

According to Anders, the big "target areas" for 4.0 are:

  • More declarative programming (a la LINQ)
  • More dynamic features
  • Concurrency  management

Anders has brought in some dynamic language guys (IronPython and (to a much lesser extent) VB).  They all spoke about different things they're interested in adding to the language.  As dynamic languages are being introduced into the .NET platform, other .NET languages are looking at ways of better integrating with these languages and the libraries written in them.  However, C# will not loose its static typing. 

Another example of what they are talking about is scripting.  Its hard to use a statically typed language used as a scripting language within another application.  IronPython has been the current choice for this internally in Microsoft. 

Listening to Anders, the big push seems to be parallelism.  There is much talk about how to guarantee purity in functions and how parallelism can be implemented in different ways without placing this on the backs of the developer.  Anders doesn't want to hide concurrent execution, however.  Developers should know and understand that their code may run in parallel, but have a well-stocked toolbox to use in order to take advantage of this.

The parallelism stuff sounds promising, however I'm a bit skeptical about the ability of developers to take advantage of it.  One of the toughest things to do is think about how your code will work in a multithreaded environment and what possible issues you may have.  But it definitely is, as Anders says, the big problem that nobody is paying attention to.  Moore's law is going to be upheld by increasing cores in CPUs, not just by cramming more transistors into a single core. 

I am a bit disappointed that there wasn't any mention about adding more language features to bring testing forward.  There are a few areas where some compiler work could help make it much easier to do....


Tags:
Categories: CLR | C#
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

InternalsVisibleToAttribute and Strong Named Assemblies Step by Step

April 9, 2008 12:17 by Will

One of the hassles with testing is that best practices and OO design often makes it very difficult to thoroughly test your code.  We should be marking classes internal to our assemblies unless we specifically wish them to be part of the public API of our DLL's.  This means to test these internal classes we have to use proxy classes that can instantiate and invoke members of these internal classes via reflection.  Visual Studio provides for some auto-generated code for this, but it can be a bit unwieldy and is not available in all versions of VS.  It would be easier if we could specify a test assembly as having access to all these internal classes.

Another case where we might want to make our internal classes available to specific outside callers is for security purposes.  If we don't want anyone but ourselves to use a specific DLL, we would want to mark all classes internal to the DLL and specify only those assemblies with our strong name have access to them.

The InternalsVisibleToAttribute allows us to do this.  According to the documentation, the syntax is pretty easy:

[assembly: InternalsVisibleTo("MyTestsLol")]

This would allow assembly MyTestsLol.DLL access to the internal classes of the assembly where this attribute is located.  And this works great.  For unsigned assemblies only.  When you sign the assembly you wish to mark with this attribute, things get more complex.

Lets say you have two assemblies, My.DLL and MyTestsLol.DLL.  You add the above attribute to the AssemblyInfo.cs file within the My.DLL project.  Everything works great; you can access and test all internal classes in My from within MyTestsLol.  But you're moving to a production oriented environment and you decide that you should be signing your assemblies, because you've read that's what professional .NET developers do.  So you sign My.DLL and build the project:

Friend assembly reference 'MyTestsLol' is invalid. Strong-name signed assemblies must specify a public key in their InternalsVisibleTo declarations.

Now you're screwed.  And if you Google this, you'll still be screwed because most of the information about InternalsVisibleTo and strong named assemblies is either wrong or too cryptic to understand.  If you find yourself at this point, here is the step-by-step procedure how to get this working again.

Gimme three steps to fix

image First, you will need to sign every assembly you wish to grant access to your internals.  Open up the properties editor for the assembly you wish to give access to, in this case MyTestsLol.DLL, and select the Signing tab.

I'd suggest creating a new, throw-away key pair for test assemblies.  For assemblies you are going to distribute you should use your regular key pair.

Second, you must extract the public key from the public/private key pair, then display the public key.  This is a two-part process that is necessary in order to get the correctly encoded version of the public key. 

Open the Visual Studio command prompt (All Programs -> Visual Studio 2005/8 -> Visual Studio Tools).  Browse to the directory where the new public/private key pair is located.  At the prompt, enter the following command (the name of the key pair (.snk) may be different if you chose a different name for the strong name key file):

sn -p fortestsonly.snk publickey.pub

This creates a file, called publickey.pub, that contains the public key portion of the public/private key pair in binary format.  Next, you need to view the public key in an encoded format (I believe its Base64) that you can use.  Do this via the following command:

sn -tp publickey.pub

This displays both the full public key and the public key token, which is a much smaller hash of the full public key.  You'll need the full public key (the token will not work), so select it and copy it out of the console.  Consoles suck, so you'll have to remove all the newline's when you paste it into your assembly. 

Finally, adjust your InternalsVisibleTo argument to add the public key (the public key should reside on a single line and be roughly three hundred something characters long):

[assembly: InternalsVisibleTo("MyTestsLol, 
    PublicKey=0024...8db5")]

The ellipsis is just to keep the key from blowing up my blog's layout. 

This will now work, and you can reference internal types from the MyTestsLol assembly.  Unfortunately, there isn't an equivalent attribute you can place on a type to allow its internals be visible to another type or another assembly, which would have made unit testing private methods a snap.  I'm not sure exactly why we don't have this kind of facility in the .NET platform.  Maybe in 4? 

kick it on DotNetKicks.com
Tags:
Categories: CLR | Testing | Tips
Actions: E-mail | Permalink | Comments (2) | Comment RSSRSS comment feed