none
Reference Assemblies

    Question

  • Hi all,

    I need to reflect some assemblies. Is it possible to add those assemblies to the current application so that GetReferencedAssemblies() return them for reflection ?

    Thank you

    Saturday, January 05, 2013 4:36 PM

Answers

  • VS is "Visual Studio" and IMO "In my opinion". I gave this a look but my understanding was that you were trying to find out which assembly includes a particular class name.

    If you have both an assembly name and a class name you can use :

    using System;
    using System.Reflection;
    namespace ConsoleApplication1
    {
        class Program
        {
            public static void Main()
             {
                const string assemblyName="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
                Assembly a = Assembly.Load(assemblyName);
                object b = a.CreateInstance("System.Windows.Forms.Button");
                Console.WriteLine("I am a {0}.",b.GetType());
                Console.ReadKey();
            }
        }
    }

    It shows "I'm a System.Windows.Forms.Button" even if System.Windows.Forms is not referenced.

    It seems the confusing part is the temptation to just use a file name to locate the assembly. This is not a problem when it is a physical file in your application directory but the Global Assembly Cache is a logical view and, as far as I know, can actually contain mutiple versions of the same assembly at the same time so using just a partial name would be not reliable (and MS obsoleted an API call that allowed to load an assembly from the GAC with a partial name likely because of that). So IMO it's likely best to always use the full assembly name for GAC assemblies so that you are 100% sure to really load the assembly version you want...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    • Marked as answer by FromJava Thursday, January 10, 2013 6:12 AM
    Sunday, January 06, 2013 2:00 PM

All replies

  • Hi,

    What happens if you try ? I don't see why it wouldn't work. My first thought would be still to use Assembly.LoadFrom as I see no reason to reference those assemblies if they are not needed for the code to run (or perhaps as resources if your goal is to make sure they ship with your app ?).


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    Saturday, January 05, 2013 4:46 PM
  • Why would you want to reflect references that you can use "normally"?

    --
    Mike
    Saturday, January 05, 2013 4:53 PM
  • Hi Patrice,

    How can you use Assembly.LoadFrom() to reflect "System.Windows.Forms.Button" for example ?

    In a recent thread (Assembly Name) , Ehsan Mohammadi, proposed a solution to get the DLL file name where "System.Windows.Forms.Button" exists. It is a good and working solution. However, I thought, if I could, somehow, add "System.Windows.Forms" as a referenced assembly, then I could use GetReferencedAssemblies() to return and use it. This way, I won't need to search the GAC directories looking for the assembly I need.

    Saturday, January 05, 2013 5:37 PM
  • System.Windows.Forms.Button is a class not an assembly and it would be likely already in most Windows applications anyway (isn't your app Windows Forms based ?)...

    I would suggest to explain first what you are trying to do. Knowing what is your goal could make easier to understand what is the problem you get or even sometimes allow an alternate and possibly simpler approach to what you are trying to achieve..

    Gave a quick look at your earlier thread and I'm not even sure it could be done. For now my understanding is that you want to feed your application with an arbitrary user provided class name (for which purpose ?) and you would like a way to retrieve the assembly to which this class belongs without having to inspect each and every assembly ?

    Knowing your goal could be easier. For example if I wanted to provide a web site to provide a web site that provides the assembly name from a class name to developpers I would just create a database by inspecting all assemblies once for all (of course it would be likely not that usefull as VS allows to inspect all .NET assemblies). IMO we definitely needs to understand your overall goal.

    Or if you know your code will need to create instance from classes in System.Windows.Forms, then just add a reference to your project...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".



    Saturday, January 05, 2013 8:00 PM
  • Hi Patrice,

    My earlier thread is under the name "Assembly name", please search for it in this forum, and you will find all the details.

    As for my gloal, it is simple. I come from a Java background and I just started learning c#. I am experimenting with all aspects of the language.

    Inspection (reflection) is a great feature that I always look at when learning a new language.

    You mentioned terms like VS and IMO. What are they ?

    Let us say I get, as input, a class name and an assembly file name, and I want to use reflection to create an instance of this class. If this assembly is a normal assembly in some directory, I would use the following to get the class type:

    String Name;
    Name = AssemblyName.GetAssemblyName ("files.dll").FullName;
    Type.GetType("hello2,"+Name);

    Here "files.dll" is the assembly file name and "hello2" is the name of a class. Simple and works.

    But I found that assemblies such as System.Windows.Forms are located in the GAC and cannot be accessed directly using this simple code. Therefore, our friend in my earlier thread suggested a very good way to access those assemblies in the GAC and I tried it and it worked too.

    However, the way suggested seemd a bit complex. So, I was wondering if I could just add a reference to this assembly to my application, I could use the method GetReferencedAssemblies() to get the "System.Windows.Forms" assembly. But how. At the end of your post, you said:

    "Or if you know your code will need to create instance from classes in System.Windows.Forms, then just add a reference to your project..."

    How can I add a reference to this assembly to my application so that it is returned when using GetReferencedAssemblies(). Assuming that I am not using any development environment, just my simple notepad.

    Sunday, January 06, 2013 7:11 AM
  • "How can I add a reference to this assembly to my application so that it is returned when using GetReferencedAssemblies()."

    You don't. GetReferencedAssemblies will return only references that are actually used by an assembly. If you specify a reference on the compiler command line or in C# project but then you don't use a type from the referenced assembly then the reference is ignored during compiling and GetReferencedAssemblie won't get it.

    IMO, it's pointless to do such a thing anyway. If you add a reference to an assembly then you have access to its types directly, you don't need reflection for this.

    But you can do something like this if you really need to get a type by name in such a case:

    Type buttonType = typeof(System.Windows.Forms.Application).Assembly.GetType("System.Windows.Forms.Button");

    Sunday, January 06, 2013 9:45 AM
  • Have you considered using System.Process.Start("gacutil /l") to generate the GAC contents?  You could then use that to find an assembly by name at the time you need it.  I am not sure I follow how your applicaiton is going to work, but that would allow listing the assemblies in the GAC which appears to be part of your goal.
     
    BTW (by the way) VS means Visual Studio and IMO means In My Opinion.

    --
    Mike
    Sunday, January 06, 2013 12:38 PM
  • VS is "Visual Studio" and IMO "In my opinion". I gave this a look but my understanding was that you were trying to find out which assembly includes a particular class name.

    If you have both an assembly name and a class name you can use :

    using System;
    using System.Reflection;
    namespace ConsoleApplication1
    {
        class Program
        {
            public static void Main()
             {
                const string assemblyName="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
                Assembly a = Assembly.Load(assemblyName);
                object b = a.CreateInstance("System.Windows.Forms.Button");
                Console.WriteLine("I am a {0}.",b.GetType());
                Console.ReadKey();
            }
        }
    }

    It shows "I'm a System.Windows.Forms.Button" even if System.Windows.Forms is not referenced.

    It seems the confusing part is the temptation to just use a file name to locate the assembly. This is not a problem when it is a physical file in your application directory but the Global Assembly Cache is a logical view and, as far as I know, can actually contain mutiple versions of the same assembly at the same time so using just a partial name would be not reliable (and MS obsoleted an API call that allowed to load an assembly from the GAC with a partial name likely because of that). So IMO it's likely best to always use the full assembly name for GAC assemblies so that you are 100% sure to really load the assembly version you want...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    • Marked as answer by FromJava Thursday, January 10, 2013 6:12 AM
    Sunday, January 06, 2013 2:00 PM
  • Thank you Family Tree Mike, "gacutil" is really a wonderful tool.

    Thank you Mike Danes

    Sorry for a late reply. I had to dig deep in the forum and other materials on the internet to read more about the subject.

    Thursday, January 10, 2013 6:20 AM