从表达式中提取数据<Func<,>>
Extracting Data from Expression<Func<,>>
我在从 Expression<Func<,>>
中提取一些数据时遇到了一些麻烦,并且在解释我想要的内容时遇到了更多麻烦。
所以我休息一下 API 并且我正在构建一个可以作为 WFC 工作的方法。
意味着我不需要通过 url 调用其余的 api 但是。
构建一个接口或某种包装器,然后从该接口中我们可以提取其余的 api 控制器名称、方法和参数。
好的,让我告诉你我想象中它是如何工作的。
This is my controller interface
[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);
}
This the controller Repository
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
参数中检索这些信息吗?
这仍然是一个想法,所以它可能不会真正起作用,如果可能的话请告诉我。
对于你的非常特殊的情况:
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
的表达式更复杂或使用不带参数的调用或 non-constant 表达式参数等,这当然会崩溃
但那样的话,你根本不知道要提取哪些信息。
我在从 Expression<Func<,>>
中提取一些数据时遇到了一些麻烦,并且在解释我想要的内容时遇到了更多麻烦。
所以我休息一下 API 并且我正在构建一个可以作为 WFC 工作的方法。
意味着我不需要通过 url 调用其余的 api 但是。 构建一个接口或某种包装器,然后从该接口中我们可以提取其余的 api 控制器名称、方法和参数。
好的,让我告诉你我想象中它是如何工作的。
This is my controller interface
[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);
}
This the controller Repository
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
参数中检索这些信息吗?
这仍然是一个想法,所以它可能不会真正起作用,如果可能的话请告诉我。
对于你的非常特殊的情况:
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
的表达式更复杂或使用不带参数的调用或 non-constant 表达式参数等,这当然会崩溃
但那样的话,你根本不知道要提取哪些信息。