Reputation:
I have an abstract class named OptionalParameters to be a base class for other parameter classes.
public abstract class OptionalParameter
{
//Template Method
public string GenerateQueryString()
{
return OptionalParameterExtensions.GenerateQueryStringWithParameters<OptionalParameter>(this);
}
}
And I have a base class as OptionalParameter. TimeEntriesParameters inherits from that base class.
public class TimeEntriesParameters : OptionalParameter
{
//Some Properties
}
So i want to generate a query string with my inherited classes properties. Then i wrote an extension method for that purpose.
public static class OptionalParameterExtensions
{
public static string GenerateQueryStringWithParameters<T>(this T optionalParameters) where T : OptionalParameter
{
//Generates and returns query string with properties of T type
}
}
After applying the structure stated above for the classes that inherits from base class with a usage stated below.
TimeEntriesParameters parameters = new TimeEntriesParameters();
string queryString = parameters.GenerateQueryString();
How can I create a generic template method for every OptionalParameter
EDIT: My real purpose is to read classes properties as below and then return a string like "?page=1&fromDate=20150728" etc.
public class TimeEntriesParameters : OptionalParameter
{
[EntityOptionalParameter(ParameterName="page")]
public int Page { get; set; }
[EntityOptionalParameter(ParameterName = "fromDate")]
public DateTime FromDate { get; set; }
[EntityOptionalParameter(ParameterName = "fromTime")]
public DateTime FromTime { get; set; }
[EntityOptionalParameter(ParameterName = "ToDate")]
public DateTime ToDate { get; set; }
[EntityOptionalParameter(ParameterName = "ToTime")]
public DateTime ToTime { get; set; }
[EntityOptionalParameter(ParameterName = "SortOrder")]
public Enumerations.SortOrder SortOrder { get; set; }
[EntityOptionalParameter(ParameterName = "UserId")]
public int UserId { get; set; }
}
So i didn't want to write a method for every class to generate query string. I think I can put a template method in OptionalParameter base class and create the string by the class properties types and attribute properties.
Upvotes: 0
Views: 371
Reputation: 2717
The type parameter in GenerateQueryStringWithParameters<T>()
is useless, since you're always calling the method as the type parameter OptionalParameter
. You can therefore rewrite the method as GenerateQueryStringWithParameters(this OptionalParemeter optionalParameter)
.
In order to generate the query string, you need to use reflection to loop through the properties in the class of optionalParameter
and check if they have an EntityOptionalParameter
. Assuming you can access the ParameterName through the property EntityOptionalParameter.ParameterName
, you can do the following:
public static string GenerateQueryStringWithParameters(this OptionalParameter optionalParameter)
{
var props = optionalParameter.GetType().GetProperties()
.Select(x => new { Prop = x, Attr = x.GetCustomAttribute<EntityOptionalParameter>() })
.Where(x => x.Attr != null); // Get all properties that have the attribute
var sb = new StringBuilder("?");
var first = true;
foreach(var prop in props) // Loop through properties
{
if (first)
{
first = false;
}
else
{
sb.Append("&")
}
sb.Append(prop.Attr.ParameterName); // Append property name
sb.Append("=");
sb.Append(prop.Prop.GetValue(optionalParameter)); // Append property value
}
return sb.ToString()
}
Upvotes: 1