简体   繁体   中英

Use web api to dynamically call class library

We have an existing API written in Vb.Net as class library which some of our customers use. Now we want this approach to be changed and expose an web api which in turn will call the class library.

This is how it works, user will pass in method name, class name, parameters for constructor and method as JSON string. Using reflection we have to invoke the class library based on the names passed in. I was able to achieve creating instance of a class and execute the method. Problem is passing parameters for the methods. Because we receive the parameters as json object in API, how to convert this data to type accepted by the methods in class library which we will know only on run time?

[ActionName("invokeapi")]
    [HttpPost]
    public IHttpActionResult InvokeAPI([FromBody]Newtonsoft.Json.Linq.JObject pClientData)
    {
        try
        {
            PostData obj = Newtonsoft.Json.JsonConvert.DeserializeObject<PostData>(pClientData.ToString());
            obj.MethodParameter = Newtonsoft.Json.JsonConvert.DeserializeObject(pClientData.GetValue("methodparam").ToString());

            return Ok();
        }
        catch (Exception ex)
        {
            return BadRequest(ex.Message);
        }
    }

public class PostData
{
    [DataMember(Name = "classname")]
    public string ClassName { get; set; }

    [DataMember(Name = "methodname")]
    public string MethodName { get; set; }

    [DataMember(Name = "parameters")]
    public string[] Parameters { get; set; }

    [DataMember(Name = "methodparam")]
    public object MethodParameter { get; set; }
}

Here, data within obj.MethodParameter is of type JArray. How can we convert this to the required type dynamically based on the class name passed in from client (ClassName property).

Is it correct to say that when you get the request you're going to just do something with the object, but the actual class you invoke to handle the request at runtime depends on the type of the request?

One suggestion is just to have multiple API methods. Within an application we wouldn't just have a method like DoSomething(object parameter) and determine at runtime what to do based on the type of parameter . If we wouldn't do it within an application, I'm not sure if it makes sense to expose that sort of interface through an API. We specify the method that we want to call by calling that method , not by calling a "universal" method and passing parameters to it indicating which method we really want to call.

It's also better if consumers of your API don't know how functionality is implemented. They just say what they want to do. They don't know the names of the classes or methods used to carry out those functions. Your API (like any other interface) creates an abstraction. You can change your implementation without changing the API.

That would be my first suggestion. Do that, and you don't solve the problem - you make the problem disappear.

That being said:

If you know the type that parameter requires, you can do this - I'm being a little verbose for clarity:

var parameterType = typeof(TheParameterType);
var deserialized = JsonConvert.Deserialize(pClientData.GetValue("methodparam").ToString(), 
    parameterType) as TheParameterType;

That's going to attempt to deserialize the string to a given type so that you pass it to a strongly-typed method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM