how to get the class name at run time from a generic method that is in another class?

229 views Asked by At

I am trying to generate my baseurl using UriBuilder. I have created a generic "GetRequestUrl" which is in my TestUtil class. How can I get the name of my Test class at run time using this method and append to the string serviceAPI

//Here is the GetRequestUrl method in my TestUtil class

public class TestUtil
{
        public string GetRequestUrl(string serviceName)
        {
            string serviceAPI = this.GetType().BaseType.Name;
            var requestUrl = new UriBuilder();
            requestUrl.Scheme = "http";
            requestUrl.Host = "svc-" + serviceName + "." + 
       ConfigurationManager.AppSettings["TestEnvironment"] + "-example.com/api/";
            requestUrl.Path = serviceAPI;
            Uri uri = requestUrl.Uri;

            return uri.ToString();

        }
}

//Here is my Test class where I want the Class name "TestClass" to append to serviceAPI string at run time, but I am getting TestUtil. I have tried following..

this.GetType().Name;

this.GetType().BaseType.Name;

MethodBase.GetCurrentMethod().DeclaringType.Name;

public class TestClass
{
TestUtil util = new TestUtil();
    [Test]
    public void Method1()
{
     string fullUrl = util.GetRequestUrl("APIServiceName");

}

}
1

There are 1 answers

13
RyanJMcGowan On

You need to pass a class in as a parameter to the GetRequestUrl, or the string you want to append. A string is better because it prevents you from needing to change code in the future to adopt to a different practice. To do it the way you seem to want to do is using reflection, which should be avoided if you can do it this way instead:

public class TestUtil
{
    public string GetRequestUrl(string testType, string serviceName)
    {
        string serviceAPI = testType;
        var requestUrl = new UriBuilder();
        requestUrl.Scheme = "http";
        requestUrl.Host = "svc-" + serviceName + "." 
        +     ConfigurationManager.AppSettings["TestEnvironment"] + "-example.com/api/";
        requestUrl.Path = serviceAPI;
        Uri uri = requestUrl.Uri;

        return uri.ToString();
    }
}

public class TestClass
{
    TestUtil util = new TestUtil();
    [Test]
    public void Method1()
    {
        string fullUrl = util.GetRequestUrl(this.GetType().ToString(), "APIServiceName");
    }
}

Another option is to pass it in at the constructor and store it as a private variable, which centralizes the data so that you only pass it in once. Using an interface is preferable to a class:

Using an Interface method:

// An empty interface is fine.
// TestUtil will then require a ServiceAPI for it to be created using it's 
// constructor as a guarantee.
public interface IServiceAPI { }  

using System.Reflection;
public class TestUtil
{
    private _service;
    
    // TestUtil requires a ServiceAPI class.
    public TestUtil (IServiceAPI service) 
    {
        _service = service;
    }
    
    public string GetRequestUrl(string serviceName)
    {
        string serviceAPI = _service.GetType().Name; // Get the class name.
        var requestUrl = new UriBuilder();
        requestUrl.Scheme = "http";
        requestUrl.Host = "svc-" + serviceName + "."
        + ConfigurationManager.AppSettings["TestEnvironment"]
        + "-example.com/api/";
        requestUrl.Path = serviceAPI;
        Uri uri = requestUrl.Uri;

        return uri.ToString();
    }
}
// implement the IServiceAPI interface on TestClass.
public class TestClass : IServiceAPI 
{
    // passing in TestClass here using "this".
    TestUtil util = new TestUtil(this); 
    
    [Test]
    public void Method1()
    {
        string fullUrl = util.GetRequestUrl("APIServiceName");
    }
}