Sunday, June 9, 2013

Assembly Reference - Best Practice

Introduction: 
             
               Its obvious that the applications do have references to one or the other assemblies to accomplish their job. The CLR looks for the referred assemblies in global assembly cache, any private path added to the app domain or one of the special folder called bin (i.e. current directory of the executing assembly).
             
             While working with Visual Studio IDE, we refer lots of related libraries using add reference tool. When we compile the code, the referred assembly files are copied from the source location and placed into the special directory called bin, so that the application can find those assemblies at runtime and load them into memory. If we refer the assemblies wrongly, then there will always be a configuration problem which we encounter, when we move the application from one location to another. This article discuss about those issues and possible solutions by providing some best practices.

Background: 
         
            It was very unfortunate situation that, my system has changed 3 times in last one month. Still there is one more chance to change! Each time the system has changed, I had to setup the currently working project. The project uses Microsoft Enterprice Library and some assemblies in it. The problem with the setup is that, the project fully relies on GAC for these assemblies and the bin folder of our project is readonly by default. Hence, the compiler is failing to copy the files from GAC to bin. Also, I forget to remove readonly attribute from the bin folder each time, causing the application to fail on runtime by giving following error, or sometimes some other error with InnerEdxception as this:

Could not load file or assembly 'xxx' or one of its dependencies.
The system cannot find the file specified.

Fixing the above issue is simple though, it wastes our time which we can save otherwise. This and my previous some other experience made me to come-up with a best practice to avoid this problem.

Wrong Approach: 
  1. Referring assemblies from bin directory.
  2. Not referring anything and making the assembly available via bin folder.
  3. Relying on GAC for almost every assembly.
The first and second approach is completely deprecated(NEVER DO THAT). Third approach is okay though, personally I prefer to have my own copy(because, its good for portability - specially in web-applications). Usually, placing the assemblies in GAC is preferred only for shared assemblies.

What is bin folder?

         The bin stands for binary. By default, in visual studio it is configured as the output folder for your build code.


In Visual Studio, you can change this to any other directory to obtain the build code(PE file). When you right click to your project or solution in visual studio and click on 'Clean', it clears the output directory and as soon as you build your project, new build files will be placed there. Ususlly, the new build files will  override the existing files in output directory when we rebuild our projects but sometimes there will be some glitches & we need to execute the clean command explicitly or we may need to delete the output folder from file-system manually.

Why referring and placing the assemblies on bin is bad idea?

         Since bin is an output folder, each time you build your code the new files will override the existing one in bin. However, this won't cause any problem to us but there are situations like:
  1. Sometimes Visual Studio takes older version assemblies for execution and we may need to delete the bin folder to overcome from this issue.
  2. We may need to remove bin and obj folder to reduce the size while porting the application.
As you can see, there are situations where bin folder needs to be deleted or recreated. Hence, it is not good to depend on this directory for required assemblies. 

Best Practice:
  1. Within the applications root directory, create a folder called Lib, Library or whatever you prefer.
  2. Place the required assemblies there.
  3. Refer them in the application using Add References tool of visual studio.
This way you can always be safe that required assemblies are exists and available all the time. Also, you can delete or recreate the bin folder without any issue. If you follow this simple best practice, no other configurations are required to setup your application on any machine.

NuGet Package: 
           
            Before I conclude my topic, here is an interesting tool to introduce (You might already been using it, if you work with MVC projects - at least to setup your project). NuGet is a tool, which helps you to port your application easily by reducing or completely eliminating the configuration burdens.

          Even this tool uses the same pattern for assembly reference. It creates a folder called packages on the root of your application and modifies your project file to refer the assemblies from that location.

Conclution: It is bad idea to refer assemblies directly from bin folder. Rather, I recommend to create a dedicated folder for this purpose and refer the assemblies from there. This enables you to port and configure the application easily.