2

I have lots of classes reflecting my screen Repository from White/UIAutomation. To use repository I need to create lots of classes that reflect screens of my application windows.

To create a repository I use the following method:

var repoReport = repository.Get<MyClassRepresentingWindow>("WindowTitle", 
InitializeOption.WithCache);

it passes a generic type which is a Class I prepared.

What I want to do is to create a Dictionary(stringClassName, string windowTitle) or any Map to pass to that method. The problem is can't pass className like in Java ClassForName.

I tried System.Activator but without any success.

Object configObj = System.Activator.CreateInstance(c);
Type c = System.Type.GetType("Namespace.MyClassRepresentingWIndow");

var myClass = System.Reflection.Assembly.GetExecutingAssembly().CreateInstance("Namespace.MyClassRepresentingWIndow");

Type type = assembly.GetType("Namespace.MyClassRepresentingWIndow");
object obj = Activator.CreateInstance(type);

var repoReport = repository.Get<c>("WindowTitle", 
InitializeOption.WithCache);

var repoReport = repository.Get<c.Name>("WindowTitle", 
InitializeOption.WithCache);

Update1 Guys, I'm not sitting in front of the code but I'll try to make my question less complicate.

This is a method which I found in the White repository that I think I use: https://github.com/petmongrels/white/blob/itemsmap/Components/Repository/Source/ScreenRepository.cs

public virtual T Get<T>(string title, InitializeOption option) where T : AppScreen
    {
        ClearClosedScreens();
        AppScreen screen;
        var repositoryCacheKey = new ScreenRepositoryCacheKey(title, typeof (T));
        if (!screenCache.TryGetValue(repositoryCacheKey, out screen))
        {
            Window window = applicationSession.Application.GetWindow(title, IdentifiedOption<T>(option));
            screen = GetScreen<T>(window);
            screenCache.Add(repositoryCacheKey, screen);
        }

        if (screen != null)
            sessionReport.Next(typeof (T));
        return (T) screen;
    }

As I remember VS displayed .Get as a .Get<"class" type>. I'm sorry I can't express myself better. Please have a patient with me because I'm not familiar with this terminology.

Update2

At the end I want to get something like this:

var repoReport1 = repository.Get<MyClassRepresentingWindow1>("WindowTitle", InitializeOption.WithCache);
var repoReport1 = repository.Get<MyClassRepresentingWindow2>("WindowTitle", InitializeOption.WithCache);
var repoReport1 = repository.Get<MyClassRepresentingWindow3>("WindowTitle", InitializeOption.WithCache);

And I have a code of MyClassRepresentingWindow{1,2,3}. I just don't know how to pass class name to Get method. On input I have a string name of this class. On output I want to deliver something that this method .Get<T> can get. I hope you can understand me now.

Koen
  • 2,501
  • 1
  • 32
  • 43
Robert Gonciarz
  • 363
  • 2
  • 8
  • 15
  • I'm confused as to what you are trying to do. if you can narrow down your problem and remove the noise it may be more clear what you need to do. – Jason Meckley Dec 22 '11 at 16:38
  • 2
    You can use Reflection. Check this post: http://stackoverflow.com/questions/232535/how-to-use-reflection-to-call-generic-method – Strillo Dec 22 '11 at 16:39
  • How is Repository.Get working with the generic parameter? One would think it would be creating objects with Activator as well. – Steve Danner Dec 22 '11 at 16:58
  • I updated text - I added a method code that I think I'm using. Guys I won't be able to check your advise/solution right now. I'll do that defiantly just after Christmas. Mary Christmas and a happy New Year! – Robert Gonciarz Dec 24 '11 at 09:14

2 Answers2

3

In order to call this with a variable type argument, whose value is only known at run time, you need to use reflection. I assume that you know how to get the MethodInfo representing the repository's Get<T> method.

Once you have that, this example illustrates the basic idea how to use the MethodInfo object. The example assumes that the repository class is called Repo; change that as needed:

object InvokeGenericMethod(Repo repository, MethodInfo method, Type typeArg, string arg1, InitializeOption arg2)
{
    MethodInfo constructedMethod = method.MakeGenericMethod(typeArg);
    return constructedMethod.Invoke(repository, new object[] { arg1, arg2 });
}

You could make this more generic, of course, but that would have made the example less clear.

phoog
  • 42,068
  • 6
  • 79
  • 117
1

I believe what you want is something like this:

    public string GetName<T>()
    {
        return typeof(T).Name;
    }

That causes the following unit test to pass (the "Basic Math" is just a type I had laying around in my scratch application):

    [TestMethod]
    public void Test_Of_Generic_Type_Name()
    {
        var myBuilder = new GenericNamer();

        Assert.AreEqual<string>("BasicMath", myBuilder.GetName<BasicMath>());
    }

You could also use the type's full name, assembly, etc. Here's some more information on what you can pull out of the Type class using reflection:

http://msdn.microsoft.com/en-us/library/system.type.aspx

Erik Dietrich
  • 6,080
  • 6
  • 26
  • 37
  • Hi Erik, thanks for your answer but I think I need something opposite. On input I have a string name of my class which I know and I have a working code of this class. On output I want to deliver something that this method .Get accepts. I hope you know what I mean – Robert Gonciarz Dec 24 '11 at 09:24