#Google Analytic Tracker

Pages

May 30, 2007

InternalsVisibleTo and Strong-Name signed assemblies

 

By now I am guessing only newbie like me would encounter this issue.  Today I was working on my project for my friend. Basically I am writing some kind of user name checking tool that can be call externally by a unmanaged program.  So, I figured that I need to expose my assembly as a COM object. I haven't test out my class yet, but hopefully it works.

Based on the article from my favorite CodeProject website:

Calling Managed .NET C# COM Objects from Unmanaged C++ Code

I need to accomplish 3 things

My class must be implement a specific interface

Both the interface and the class must have a GUID attribute to identify themselves

The assembly must be a strong-name type. (This is the part I am not sure why it has to be a strong-name type, but I am guessing it is because the writer decided to add the assembly to the GAC in his example from the article)

So, to ensure that I have a strong-name type, I followed the article procedure to create a snk (Strong Name Key) file.

Using Visual Studio 2005 Command Prompt,

> sn -k TestKeyPair.snk

The article suggested to do add "[assembly: AssemblyKeyFile("TestKeyPair.snk")]". After trying it, VS2005 warned me that I should added the snk file thought the Project->Properties->Signing tab, which I did

Now, here comes the tricky part, I have a UnitTests that test my internal method of my class.

SO, LET COMPILED

Error: Friends assembly must be strong-named signed (some error like that)

Ok, so it looks like I need to make sure that my UnitTests assembly need to be strong named too. So, I created another snk file call UnitTestsKey.snk, and added this file to my UnitTest project

Try again

   1:  
   2: [assembly: InternalsVisibleTo("UnitTests"]
   3:  
   4: // Compiling Error
   5: // Error 1 Friend assembly reference 'UnitTests' is invalid. 
   6: // Strong-name signed assemblies must specify a public key in 
   7: // their InternalsVisibleTo declarations.

What the heck is this "Public Key" I am missing? After hitting the F1 (for help, really I used F1 for help). Once again, MSDN helps doesn't explain much, especially for newbie like me. Let's GOOGLE it.

Ok, somehow I need to retrieve the public key from either the compiled DLL, or from the snk file.

This blog explains what I need to do, but it missing explain one important thing!

Which DLL's or SNK public key I need? My class, or my UnitTest class? It is important to know because I was confused on how this strong name type work.

After trials and errors, obvious it is the UnitTests's public key that I want.  The idea is that since my UnitTest is strong named and it is encrypted with this special snk file, to allow My Class shares its internal method, it needs to know the UnitTests assembly's public key.

Following the blog's explanation, I obtained the public key though the UnitTests.snk file. I can't get public key from the UnitTest assembly because it didn't compiled.

3rd Try

   1: [assembly: InternalsVisibleTo("UnitTests, PublicKeyToken=8c40a2440ba23747")]
   2:  
   3: // Compiling Error
   4: // Error 1 Friend assembly reference 'UnitTests, PublicKeyToken=8c40a2440ba23747' 
   5: // is invalid. Strong-name signed assemblies must specify a public key in their 
   6: // InternalsVisibleTo declarations.
   7:  

WTF? Let's Google it again.... hmmm... interesting some site is using PublicKeyToken, but some other doesn't, it uses PublicKey in the parameter string. Let use PublicKey

4th Try

   1: [assembly: InternalsVisibleTo("UnitTests, PublicKey=8c40a2440ba23747")]
   2:  
   3: // No compiling Error
   4: // but with Warning
   5: // Warning 1 Assembly reference 'UnitTests, PublicKey=8c40a2440ba23747' 
   6: // is invalid and cannot be resolved

Well, better, but when I compile my UnitTests project, it still failed. My UnitTests doesn't see the internal method of my Class....must be something do with the warning.

Finally, after reading more from an webpage (which unfortunately the webpage link is no longer working), it turns out that in Visual Studio 2005, you need to get the hex value for your public key.

5th Try

   1: [assembly: InternalsVisibleTo("LicenseKeyGeneratorExtendedTests, PublicKey=00240000048000009400000006020000002400005253413100040000010001000735a079d1bc7b8ea2b3e6706544e7396e4f3110b49c6529361d83ed66111c2fa4b38bbfb3d074d8ce76ed0a2813a2b9901ae0a88b79c85712e3ec4852fef4435426269f1009e2d79dc90644db171ec0566919f4945b06bce3603cc7af098d2774ec80b79bd182d4394bf75f775d0fecbf1b4ecb21a53aa6b0d9e218a1c223d0")]
   2:  
   3: // No Errors or Warnning

Finally, my solution compiled!

-------------------------------------

Update - Feb 11, 2009

If you still having trouble of making an assembly visible to another, check if you have the following line in your assembly.cs file and remove them:

[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

Recently I tried to expose internal methods in a project to a unit test project.  My solution wouldn't compile, and after checking the assembly.cs in the project, I found these two line. Initially I thought it doesn't really do anything, but after I removed it, the solution compiled. I don't know why it was there in the beginning, but in any case, it works now.

Update – Mar 11, 2009

Some of the references were broken and they are now fixed.

Other References

Strong Names Explained

May 8, 2007

Goodbye ReSharper (at least for now)

 

ReSharper is a very intelligent tool and I like it a lot. It helps me analyze unfamiliar code much easier.

Unfortunately its performance slows down a lot when your project that has large data model and other code generated classes.

I have classes that contain more than 10,000 LOC due to code generation. Even a 4000 LOC file takes a while for ReSharper to parse on my machine, which only has 1GB of ram.

In my case, ReSharper is a memory hog. I often have to check my memory usage so that I know when it is a good time to restart VS2005. Restarting VS2005 is no fun at all. It takes time to shutdown and load the solution.

For some reason, ReSharper memory usage keep increasing as time pass. I am not sure if there is a bug, memory leak, or it caches all the parsed data.

I see the memory of devenv.exe Mem Usage goes as high as 700MB and 1500MB VM size. Page Fault is so high that my computer basically is thrashing.

The memory issue is a big issue since the first time I used ReSharper 2.0 in another company. However, because the project I worked on doesn't involve much code generation, ReSharper performance is fairly alright. Even so, I occasionally unload ReSharper (though registry importing), so that I can quickly open up a solution and inspect the code.

My colleague suggested if ReSharper has a button to stop code analyzing, or skip parsing certain classes for increase in performance, he would like to install ReSharper again. I just hope that next release of ReSharper would have a better perform.

SQLServer "IS NULL", "IsNull()" and "= null"

Today, I ran into something very interesting.. well.. to me at least.

After coding a lot with C#, the NOT EQUAL "!=" syntax is pretty much embedded into my dairy operation in my brain.

Anyhow, surprised to me, when I run the following:

select * from someTable where someKey != null;

is not the same as:

select * from someTable  where someKey IS NOT NULL;

It turns out that I forgot using != performs a comparison operation instead of checking if the value is null. Hence, it try to test if someKey contain a value that matches the value that represent the database "null".

The comparison operation returns UNKOWNOW if either of both operands is null.

Moreover, after digging more about this issue, if you use UDT (User Define Type) in SQL Server, you can also use columnName.IsNull property to check if the column value IS NULL or not. I am not an expert of UDT, so I will stop talking about it here. Just something to know.

References:
IS [NOT] NULL (T-SQL)
MSDN Blogs on SQL Server IS NULL vs. IsNull