tags:

views:

282

answers:

6

I'm wondering if it's possible to use reflection to locate an object at runtime? This is more of an experiment than a practical requirement.

I've used the .GetType() method on an object instance to do various things to the object, but my question is: what if I know an object of a certain type exists at runtime, but I can't refer to it by name.

As a more concrete example, suppose I have a WinForms app that loads a DLL - how might that DLL independently locate a reference to the form object in order to interact with the form, or call a public method?

Is this even possible?

+6  A: 

No, basically.

You could have some sort of horrible global map from type to "the instance of the type I'm interested in" but otherwise, no.

Basically, the WinForms app should pass a reference to the form into the DLL somehow.

Jon Skeet
A: 

Nope this is not possible, because references are implemented privately by Microsoft they are not pointers compared to C/C++, in old C/C++ you could scan your memory but in .NET there are no such tools.

Akash Kava
A: 

I didn't understand your question. When you refer to an object, do you mean you are searching for an object instance, or are you referring to searching for an object type?

In case you are looking for an instance, then the answer is no. If you are looking for a type by name at runtime, then the answer is yes.

The following line will allow you to get all the loaded assemblies in the AppDomain: AppDomain.CurrentDomain.GetAssemblies();

The instance method Assembly.GetTypes() will get you all the types in an assembly.

Edit: Forgot you knew the name of the type. You can also use Assembly.GetType(string name).

Rui Craveiro
A: 

You can design a plugin framework for your application. Here's an example:

public interface IPlugin
{
void Load(Form mainForm); //Or you can have an interface for you main form that allows your plugin to work with your form.
}

then you can find your plugins when you load an assembly at run time.

foreach(var type in assembly.GetTypes())
{
if(typeof(IPlugin).IsAssignableFrom(type))
var plugin=(IPlugin)Activator.CreateInstance(type);
plugin.Load(_mainForm);
}

Updatd: BTW as far as I know the answer to your question is no

Beatles1692
A: 

As others have answered already, no, it isn't possible in a general way.

But, for a more specific scenario, you could get a list of all Windows from the Win API, and then examine each one for the properties you are trying to seek out.

public static class Helper
{
    public static IntPtr[] GetToplevelWindows()
    {
        List<IntPtr> windowList = new List<IntPtr>();
        GCHandle handle = GCHandle.Alloc(windowList);
        try
        {
            Helper.EnumWindows(Helper.EnumWindowsCallback, (IntPtr)handle);
        }
        finally
        {
            handle.Free();
        }

        return windowList.ToArray();
    }

    private delegate bool EnumWindowsCallBackDelegate(IntPtr hwnd, IntPtr lParam);

    [DllImport("user32.Dll")]
    private static extern int EnumWindows(EnumWindowsCallBackDelegate callback, IntPtr lParam);

    private static bool EnumWindowsCallback(IntPtr hwnd, IntPtr lParam)
    {
        ((List<IntPtr>)((GCHandle)lParam).Target).Add(hwnd);
        return true;
    }
}
kek444
A: 

If you are just experimenting and trying to locate the Main Form from your DLL you could do:

//get the current process
System.Diagnostics.Process p = System.Diagnostics.Process.GetCurrentProcess();

//get its main windows handle (only works, if the form is already created)
IntPtr hWnd = p.MainWindowHandle;

//locate the form by its native handle
System.Windows.Forms.Form f = System.Windows.Forms.Form.FromHandle(hWnd) as System.Windows.Forms.Form;

Have just tested that for dependent assemblys, not for dynamically loaded ones. But it could be worth a try.

For the general issue of locating a specific instance, the question has already been answerd.

Frank Bollack