Hi, my name is Brian MacKey and I develop free open-source tools.

how to download music from youtube to computer

Please see my Github account for new upcoming projects.


Modern day internal .NET applications combine services, console applications, unit tests, winforms and asp.net web applications. These applications often share Assemblies (DLLs). With so many exe’s, updating our applications can be quite a challenge. For one thing, Visual Studio is designed to output a program with one top level exe file. Modern day applications consist of many exe’s. Its far too easy for our applications to get out of synch.

If only we could store all our assemblies in a single folder, say “C:\References” and have our applications use the assemblies in that folder. Well we can, but it requires more work than you think.

Let’s look into a simple example. [The example is intended to display the core issue with assembly versioning, not give lesson in architecture] We have two programs: Program1.exe and Program2.exe. Both programs reference “C:\References\BusinessLayer.dll”. Two Visual Studio Builds produce:

C:\OutputDirectory\Bin\Debug\Program1.exe
C:\OutputDirectory\Bin\Debug\BusinesLayer.dll (v1.0)

AND

C:\OutputDirectory2\Bin\Debug\Program2.exe
C:\OutputDirectory2\Bin\Debug\BusinesLayer.dll (v1.0)

Now, we update Program2.exe with some new functionality. We also update BusinessLayer.dll and deploy it to “C:\References”. A Visual Studio Build of Program2 produces:

C:\OutputDirectory2\Bin\Debug\Program2.exe
C:\OutputDirectory2\Bin\Debug\BusinesLayer.dll (v1.1)

Program 1 still looks like:

C:\OutputDirectory\Bin\Debug\Program1.exe
C:\OutputDirectory\Bin\Debug\BusinesLayer.dll (v1.0)

Woops, we are out of sync. Visual Studio does NOT use our original reference location after the build! It makes a copy of the file FROM that location.

Ok, so Team Foundation Server (TFS) setup for Continous Integration can solve this right? Yes, but TFS requires alot of maintenance and setup for each solution. There’s gotto be another way (and cheaper).

MSDN tells us how to load an assembly outside the bin directory. Our options are GAC, a config file or source code.

GAC: Managing assemblies in the GAC can get a little tricky. Not to mention, Referencing Assemblies from the GAC requires adding registry entries, so lets shelve that idea.
Config file: A config file is nice, but requires adding a version#. That just shifts our sync problem to config files…so lets drop that idea.

What about source code?

If we take the source code from MSDN and wrap it up in an assembly, we can add direct referencing capability to all our applications by deploying this assembly to the GAC. The following code allows one to do just that. Simply take this code and make a DLL out of it. Then, deploy it to the GAC. OR download the one I made and drag-drop it to C:\windows\assembly

using System;
using System.Reflection;

namespace BMackeyUtilities
{
    public class Utility
    {
        public static void ImportAssemblies()
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
        }
        private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
        {
            //This handler is called only when the common language runtime tries to bind to the assembly and fails.

            //Retrieve the list of referenced assemblies in an array of AssemblyName.
            Assembly MyAssembly, objExecutingAssemblies;
            string strTempAssmbPath = "";

            objExecutingAssemblies = Assembly.GetEntryAssembly();//.GetExecutingAssembly();//Get the exe assembly
            AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

            //Loop through the array of referenced assembly names.
            foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)
            {
                //Check for the assembly names that have raised the "AssemblyResolve" event.
                if (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(",")))
                {
                    //Build the path of the assembly from where it has to be loaded.
                    strTempAssmbPath = "C:\\References\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
                    break;
                }

            }
            //Load the assembly from the specified path.
            MyAssembly = Assembly.LoadFrom(strTempAssmbPath);

            //Return the loaded assembly.
            return MyAssembly;
        }
    }
}

Going back to Program1.exe and Program2.exe. I add myAssemblyInGac.dll to both programs. See how to add a reference to a file in the gac (just add a registry key to HKLM\SOFTWARE\MICROSOFT\.NETFRAMEWORK\AssemblyFolders\ and set the “Default” string value to C:\References). Then, add the following line of code to the first line in Main() in all your programs:

BMackeyUtilities.Utility.ImportAssemblies();

Now, everytime I update BusinessLayer.dll and copy it to “C:\References”, both of my programs are in sync. Imagine the time and frustration this saves with 10+ exe’s!

Homepage

Updated on 2018-06-15T20:51:45+00:00, by admin.