Rob Kraft's Software Development Blog

Software Development Insights

Archive for December, 2007

How to access the internal methods of another DLL (and compile it all with nant)

Posted by robkraft on December 26, 2007

C# provides a lot of scoping options for classes, methods, and properties.  However, one scoping option that you may think is missing is the ability to allow a DLL to reference an internally scoped method that resides in another DLL.

Why would I want to do this?

Q.      Why would you want to reference an internal method in another DLL?  Didn’t the author of the DLL scope it internal specifically to prevent such access?

A.  The answer is “Yes”, but sometimes, the author of LOWLEVEL.DLL and the author of HIGHLEVEL.DLL are the same person or on the same team and they trust each other.

Q.  So why not just scope the method as public in LOWLEVEL.DLL?

A.  The reason is that you don’t want 3rd party programmers to access the method directly; but you do want your own DLLS to be able to access them.

When would I want to do this?

There are 2 scenarios where this is common:

One scenario is that you have a method in LOWLEVEL.DLL that runs an SQL query in the database.  The method is generic and could be used by several HIGHLEVEL.DLLs, but you don’t want to make the method public because you don’t want 3rd party programmers to run SQL, you want 3rd party programmers to go through your HIGHLEVEL.DLLs that check permissions and syntax before calling the base LOWLEVEL.DLL to run the query.

Another scenario where you want to call internal methods in other DLLs is when you want to write unit tests to test those internal methods, and you don’t want to include your unit test assembly in the same solution as the DLL you are testing.

How do I do this?

To call an internal method in another DLL you must:

  1. Strong name both DLLs
  2. Update Assembly.info of the LOWLEVEL.DLL to allow the specific HIGHLEVEL.DLL access to internal methods

Strong Naming DLLs

You can think of strong-naming as a way to make your DLL globally unique.  You want to use a strong name when allowing access to internal methods; otherwise, 3rd party programmers could simply name their DLL to the simple name that your LOWLEVEL.DLL allows.

A number of articles provide information for strong naming DLLs, such as this one: http://msdn.microsoft.com/msdnmag/issues/06/07/CLRInsideOut/default.aspx, or this one: http://msdn2.microsoft.com/en-us/library/xwb8f617(VS.80).aspx

Identifying the DLLs to allow access

You must add an entry in the AssemblyInfo.cs file of the LOWLEVEL.DLL (the DLL that has the internal method to be accessed by another DLL) in order to identify the HIGHLEVEL.DLL that is allowed to access internal methods.  You do this with the InternalsVisibleToAttribute attribute (aka InternalsVisibleTo).  Unfortunately, as I researched this I found many examples that were not exactly accurate.

This example will work:

[assembly: InternalsVisibleToAttribute(@”HighLevel, PublicKey=0024000004800000940000000602000000240000…BigLongValue…”)]

  • You must include the CompilerServices namespace in AssemblyInfo.cs:
    • using System.Runtime.CompilerServices;
  • You must use the long form of your public key name.  You can obtain the long name of the public key by running the sn tool at the command prompt:
    • sn –Tp HIGHLEVEL.DLL
  • You must use InternalsVisibleToAttribute (not InternalsVisibleTo)

Compile both DLLs with their strong names.  Then, recompile the LOWLEVEL.DLL with the above attribute, and the HIGHLEVEL.DLL should be able to access internal methods of the LOWLEVEL.DLL.

One step further:

For those of you using NANT to automatically create your AssemblyInfo.cs files, you need to do three things:

  1. Add the CompilerServices namespace,
  2. Add the InternalsVisibleToAttribute attribute as shown below
  3. Include the keyfile on the csc task when building the dll.

     <asminfo output=”Properties/AssemblyInfo.cs” language=”CSharp”>

     <imports>       

       <import namespace=”System” />    

       <import namespace=”System.Reflection” />        

       <import namespace=”System.Runtime.InteropServices” />

         <import namespace=”System.Runtime.CompilerServices” />

   </imports>

<attributes>       

     <attribute type=”ComVisibleAttribute” value=”false” />

     <attribute type=”CLSCompliantAttribute” value=”true” />

      <attribute type=”InternalsVisibleToAttribute” value=”HighLevel, PublicKey=002400000480000094000…BigLongValue…” />

</attributes>

</asminfo> 

<csc target=”library”  platform=”x86″ warnaserror=”true” output=”${build.dir}/bin/${project.name}.dll” keyfile=”mykey.snk“>  

Advertisements

Posted in Visual Studio 2005 | Leave a Comment »

Free program to allow blocked outlook attachments

Posted by robkraft on December 25, 2007

I wrote my first WPF program yesterday.  The simple program allows you to unblock attachments in Microsoft Outlook.  Because this program relies on Microsoft’s new WPF technology, you must install the .Net 3.5 framework on your computer to run it.

The program gives you a list of file extensions from which you can choose for Microsoft Outlook to allow.  The program reads and writes to the registry of the local computer.  The program works for Outlook verions 9,10,11, and 12 (Outlook 2000 through 2007).

The program is based on http://support.microsoft.com/kb/829982.  It helps you get past this message “Outlook blocked access to the following potentially unsafe attachments”.

Please be aware that files with these extensions are blocked to prevent harm to your computer.  If you need to unblock an extension in order to receive a file you trust, I recommend you re-block that extension after you have received the file.  You will need to stop and restart Outlook after making a change.

Note that the settings on your Exchange server may still prevent you from receiving the file in Outlook.

My program can be downloaded from this page: http://www.kraftsoftware.com/FreeStuff/tabid/57/Default.aspx

I am working on a version that does not require .Net 3.5 (wpf).  It will just require .Net 2.0.

Posted in Outlook Utility, Visual Studio 2008 | Tagged: , , , , | 1 Comment »

Are you missing the controls in the toolbox for Visual Studio 2008?

Posted by robkraft on December 21, 2007

I downloaded Microsoft Visual Studio 2008 Express Edition (C#), installed it, and rebooted my computer.  Then I immediately went to create my first WPF application in VS2008.  I was challenged initially by the lack of controls available in my toolbox.  All of the controls were disabled.  So I went to Tools, Choose Toolbox Items, and enabled the few I wanted to start playing with (in the WPF components tab).  However, they were still disabled.
I exited Visual Studio, restarted Visual Studio, and all the controls were now available, and have been ever since.  I don’t know why they weren’t there the first time I ran the product.

Another possible reason that the controls are not enabled is simply that you need to click on the XAML form.  If your mouse is in the raw XAML window, the controls will not be enabled.

Posted in Visual Studio 2008 | Tagged: , | 11 Comments »