Извлечение данных из выражения <Func <, >> - PullRequest
0 голосов
/ 25 июня 2019

У меня небольшие проблемы с извлечением некоторых данных из Expression<Func<,>>, и у меня больше проблем с объяснением того, что я хочу.

Итак, у меня есть API отдыха и я создаю метод, который мог бы работать как WFC.

означает, что мне не нужно будет называть остальные API по URL, но. Создавая интерфейс или какую-то оболочку, из этого интерфейса мы могли бы извлечь остальные api-контроллеры Имя, метод и параметры.

Хорошо, позвольте мне показать вам, как я представляю, как это работает.

Это мой интерфейс контроллера

[Route(url: "api/")]
public interface IYoutubeController
{
    /// <summary>
    /// Get a collection of the searched youtube videos
    /// </summary>
    /// <param name="searchString"></param>
    /// <param name="pageSize"></param>
    /// <param name="relatedTo"></param>
    /// <param name="videoSearchType"></param>
    /// <returns></returns>
    [Route]
    YoutubeVideoCollection Search(string searchString, int pageSize = 50, string relatedTo = null, VideoSearchType videoSearchType = VideoSearchType.Videos);

    /// <summary>
    /// Get the playlist video contents
    /// </summary>
    /// <param name="playListId"></param>
    /// <returns></returns>
    [Route]
    List<YoutubeItem> Playlist(string playlistId);

    /// <summary>
    /// decrypted youtube video
    /// </summary>
    /// <param name="videoId"></param>
    /// <returns></returns>
    [Route(httpMethod: HttpMethod.POST)]
    Task<YoutubeVideoInfo> GetVideoAsync(string videoId);
}

Это контроллер хранилища

public static class ControllerRepository
{
    public static async Task<P> Execute<P>(Expression<Func<IYoutubeController, P>> func)
    {
        return await HttpHelper.ExecuteAsync(func);
    }
}

Теперь я могу просто вызвать мой метод следующим образом

 YoutubeVideoCollection test = await ControllerRepository.Execute(x => x.Search("Eminem"));

Вы можете видеть, что метод seach не существует, это только метод в интерфейсе.

А вот httphelper, в нем существуют PostAsync и GetAsync, а также ExecuteAsync

 private static string baseUrl = "http://xxx"
 public static async Task<P> ExecuteAsync<T, P>(Expression<Func<IYoutubeController, P>> func) 
    {
        var url= typeof(T).GetCustomAttribute<Route>()?.Url ?? ""; // eg api/
        var controller = typeof(T).Name; // eg IYoutubeContrller, will be renamed to youtube later on
        var method = // get the method from func P which is Search
        var parameters = // the parameter data from func which is Eminem
        var fullUrl= $"{baseUrl}/{url}/{controller}" 
        // and here we do PostAsync<P>(fullUrl, parameters ) Or GetAsync<P>(fullUrl, parameters )
    }

В HttpHelper ExecuteAsync я хочу получить из моего Func<T, P> имя метода Search и параметр searchString, а также значение параметра Eminem

Не могли бы вы помочь мне получить эту информацию из func параметра?

Это все еще идея, поэтому она может не сработать, просто дайте мне знать, если это возможно.

1 Ответ

1 голос
/ 25 июня 2019

Для вашего особенного чехла:

Execute(x => x.Search("Eminem"));

Вы могли бы сделать это

public static async Task<P> ExecuteAsync<T, P>(Expression<Func<IYoutubeController, P>> func)
{    
    MethodCallExpression callExpression = expression.Body as MethodCallExpression;
    string methodName = callExpression.Method.Name;
    object argument = ((ConstantExpression)callExpression.Arguments).Value;
    // do something
}

Но, конечно, произойдет сбой, если выражение, переданное в Execute, будет более сложным или использует вызовы без аргументов или аргументы с неконстантными выражениями и т. Д.
Но в этом случае вы вообще не будете знать, какую информацию извлекать.

...