Streamline Methods with a Generic Response

December 20, 2016

         Building software applications requires planning, communication, and organization.  Developers are sometimes left to make their own coding decisions without having any team standards.  Some development teams like unit testing, some teams like everything dynamic, some teams like agile, and some teams have short projects that only last a few weeks.  It can be difficult to create an efficient development process in any of the possible team scenarios.  One construct that can assist in streamlining code is to make a generic method response that contains useful information that any developer can understand and work with easily with little or no communication.  

1.) Start by making an interface type for the response.  (I called mine IResponse)

public interface IResponse<T>
{
	bool IsSuccessful { get; }
	IList<string> ErrorList { get; set; }
	T Payload { get; set; }
}

There are several things to note about what information an object of this type will have.  Any object of the IResponse type will have the desired object returned in the Payload property, an IsSuccessful Boolean stating whether or not the requested method call was successful, and a collection of error messages included for more information if there happened to be an error in the method call.  

2.) Next make a Response object implementing the IResponse interface and add a tiny bit of code to it.

public class Response<T> : IResponse<T>
{
	public Response()
	{
    		ErrorList = new List<string>();
	}

	public bool IsSuccessful => (ErrorList == null || !ErrorList.Any());
	public IList<string> ErrorList { get; set; }
	public T Payload { get; set; }
}

Now there is a concrete class implementing the interface and has the last bit of logic in there before being ready to go.  The constructor is only to initially set the ErrorList collection to an empty collection to prevent NULL errors going forward.  The IsSuccessful property has a special getter to calculate whether or not the ErrorList contains errors.  If there are no errors set into the ErrorList collection then the IsSuccessful will return true.  The Payload and ErrorList properties are basic backing field properties have no special logic added to them.

3.) Start coding!  

public class Demo
{
	private readonly IList<Person> _people;
	private readonly IList<Role> _roles;

	public Demo()
	{
            	_people = new List<Person> { new Person { Name = "Kelly" }, new Person { Name = "Bobby" }, new Person { Name = "Sam" } };
            	_roles = new List<Role> { new Role { Name = "Super Admin" }, new Role { Name = "Admin" }, new Role { Name = "User" } };

            	IResponse<Person> personSuccessResponse = GetPersonByName("Sam");
            	IResponse<Person> personFailResponse = GetPersonByName("");
            	IResponse<Role> anotherClassResponse = GetRoleByName("Admin");
        	}

    	private IResponse<Person> GetPersonByName(string name)
    	{
        	var response = new Response<Person>();

        	if (!string.IsNullOrWhiteSpace(name))
        	{
            	        var person = _people.FirstOrDefault(x => x.Name == name);
            		if (person == null)
            		{
                		response.ErrorList.Add("Person Not Found");
            	        }
            		response.Payload = person;
        	}
        	else
       	 	{
            		response.ErrorList.Add("Name is not specified");
        	}

        	return response;
    	}

    	private IResponse<Role> GetRoleByName(string name)
    	{
        	var response = new Response<Role>();

        	if (!string.IsNullOrWhiteSpace(name))
        	{
            		var role = _roles.FirstOrDefault(x => x.Name == name);
            		if (role == null)
            		{
                		response.ErrorList.Add("Role Not Found");
            		}
            		response.Payload = role;
        	}
        	else
        	{
            		response.ErrorList.Add("Name is not specified");
        	}

        	return response;
    	}    
}

Above is a simple code demonstration of the Response class being put to use.  In this case, the code is doing some logic to get a Person object twice and then get a role once.  This demo was just to show that the response can contain any necessary types as the payload because it is generic.

Some bonuses of using a generic response type are:

  • Simple to implement

  • Easy to understand

  • Creates code uniformity

  • Includes more information with return values

If you enjoy this topic or enjoy talking about development of any kind you should check out the available positions at Sparkhound.  Sparkhound is full of fun people with similar interests and motivation to provide the best possible solution to any scenario.  There are plenty of great minds to lean on and there is always room for fun!  Feel free to contact me at sam.north@sparkhound.com and/or contact Sparkhound for any further discussions, questions, or feedback.  Thanks and woot!

Sam

Information and material in our blog posts are provided "as is" with no warranties either expressed or implied. Each post is an individual expression of our Sparkies. Should you identify any such content that is harmful, malicious, sensitive or unnecessary, please contact marketing@sparkhound.com.

Meet Sparkhound

Review our capabilities and services, meet the leadership team, see our valued partnerships, and read about the hardware we've earned.

Engage with us

Get in touch with any of our offices, or check out our open career positions and consider joining Sparkhound's dynamic team.