I have an interface to a .NET service layer, which, in turn, will communicate with a third-party system via a web service. This handles a number of different tasks related to the third-party system's functionality (it is actually a bespoke CRM system, but as the context isn't relevant I will swap this out for something trivial).
The interface looks something like this:
public interface IMyService
{
CarModel GetCar(string registration);
CarModel AddCar(Car car);
PersonModel GetPerson(string personId);
PersonModel AddPerson(Person person);
}
Now, my models currently work as follows: I have a BaseResponseModel
, from which each SomethingModel
inherits. Each SomethingModel
contains some basic properties and also wraps a Something
- like so:
Base response model
public class BaseResponseModel
{
public List<string> Errors { get; set; }
public bool HasErrors
{
get
{
return (Errors != null && Errors.Count > 0);
}
}
}
Specific response models
public class CarModel : BaseResponseModel
{
public Car Car { get; set; }
}
public class PersonModel : BaseResponseModel
{
public Person Person { get; set; }
}
Here, Car
and Person
simply contain a bunch of public properties. Then, each method of my IMyService
takes its arguments, formats a request to an .asmx web service, parses the response into its response model and returns it to the caller (an .ascx codebehind).
However, the number of different ...Model
classes (not to mention that they all have different property names for their wrapped objects) is becoming ugly. I am of a mind to do something along the lines of the following:
public class Car
{
public string Registration { get; set; }
}
public class ServiceResponse<T>
{
public List<string> Errors { get; set; }
public bool HasErrors { ... }
public T Result { get; set; }
}
public interface IMyService
{
ServiceResponse<Car> GetCar(string registration);
ServiceResponse<Car> AddCar(Car car);
ServiceResponse<Person> GetPerson(string id);
ServiceResponse<Person> AddPerson(Person person);
}
My ASP.NET controls will then receive ServiceResponse<T>
from every method in IMyService
.
Is this the "conventionally correct" usage of generics in C#? Or is this simply masking deeper architectural flaws with my solution? Is there something missing from my proposed solution (though note that the implementations of the different Get
and Add
methods aren't as generic as the prototypes make them seem)?
Disclaimer: Apologies if this question is "too subjective," but it seemed too specific to be a theoretical question for Programmers.SE and a little too generic to be a question for CodeReview.SE. I am open to suggestions on how to improve the question if necessary.
Generics are similar to templates in C++ but are different in implementation and capabilities. Generics introduces the concept of type parameters, because of which it is possible to create methods and classes that defers the framing of data type until the class or method is declared and is instantiated by client code.
The first character of the name should be a letter and all characters (except the period) should be lower-case letters and numbers. The base name should be eight or fewer characters and the suffix should be three or fewer characters (four, if you include the period).
Unlike C++ and Java, C doesn't support generics. How to create a linked list in C that can be used for any data type? In C, we can use a void pointer and a function pointer to implement the same functionality. The great thing about void pointer is it can be used to point to any data type.
In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs.
I don't see a problem with this use of generics, unless you would have someone using your service from something other than .NET perhaps. I think it generates quite ugly contract names for the WSDL.
So for your use case, I'd say it's fine. I'm glad you changed from Model
to Response
as well. I was going to suggest that.
Depending on how the errors are used, I would personally prefer to raise an (aggregated) exception for them. However, if you use it for forms validation or something, I would say that's acceptable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With