patterncsharpMinor
Wrapper classes for objects returned by 3rd party APIs
Viewed 0 times
apisreturnedobjects3rdpartywrapperforclasses
Problem
I am building a WPF application which uses a third party library to fetch objects which I want to allow the user to interact with.
The objects are returned as interface types. Am I right in thinking it is good practise to create wrapper classes for these objects instead of binding directly to the interface returned e.g (ICustomer)?
If so, what is the best way to do this? My current thinking is to inject the service into my view model. Then create my own version of the customer class (
For each of these, I will create a new instance of
Is this a good approach?
I'm also unsure how to handle complex types which
Do I need to wrap the Bank Account object in a similar way as well?
The objects are returned as interface types. Am I right in thinking it is good practise to create wrapper classes for these objects instead of binding directly to the interface returned e.g (ICustomer)?
If so, what is the best way to do this? My current thinking is to inject the service into my view model. Then create my own version of the customer class (
ClientCustomer) on the client. When I call get customers on the service it will return a list of ICustomer.For each of these, I will create a new instance of
ClientCustomer passing in the ICustomer object and client customer can simply return the underlying properties. This will leave me with a list of ClientCustomer objects which I can bind to instead of binding directly to the List of ICustomer:public class ClientCustomer
{
public ClientCustomer(ICustomer c)
{
this.customer = c;
}
public string Name
{
get { return this.customer.Name;}
}
//Other properties in a similar way to Name
}
public class CustomerViewViewModel : ViewModelBase
{
ICustomerService svc;
public ViewModel(ICustomerService svc)
{
this.svc = svc;
Customers = new List();
var custs = svc.GetCustomers();
custs.ForEach(c => Customers.Add( new ClientCustomer(c));
}
public List Customers {get;}
}Is this a good approach?
I'm also unsure how to handle complex types which
ICustomer contains. For instance ICustomer has a List of Bank accounts IBankAccount. Do I need to wrap the Bank Account object in a similar way as well?
Solution
You're almost there. You have the right idea, but you missed the execution of the idea a little bit.
You've put a boundary in between yourself and the third party interface, but then you've turned around and coded against an implementation. We should code against
Right now you're probably confused.
But I can't code against that interface. I need to insulate myself from it.
You're right. You do need to insulate yourself from the third party interface. It's their boundary, not yours. You need the Adapter pattern.
You need to create your own interface that your code will work with.
Then your class implements your interface.
And all of the client code works with classes implementing the
This way, if you ever swap the libraries out, you're truly insulated. You create a new class that implements your interface and it is much easier to swap one for another. If you make this small change, I'd say you've got it right.
public class ClientCustomer
{
public ClientCustomer(ICustomer c)
{
this.customer = c;
}
public string NameYou've put a boundary in between yourself and the third party interface, but then you've turned around and coded against an implementation. We should code against
interfaces whenever possible. Right now you're probably confused.
But I can't code against that interface. I need to insulate myself from it.
You're right. You do need to insulate yourself from the third party interface. It's their boundary, not yours. You need the Adapter pattern.
You need to create your own interface that your code will work with.
interface IClientCustomer
{
string Name { get; }
}Then your class implements your interface.
public class ClientCustomer : IClientCustomerAnd all of the client code works with classes implementing the
IClientCustomer interface. public ViewModel(ICustomerService svc)
{
this.svc = svc;
Customers = new List();This way, if you ever swap the libraries out, you're truly insulated. You create a new class that implements your interface and it is much easier to swap one for another. If you make this small change, I'd say you've got it right.
Code Snippets
public class ClientCustomer
{
public ClientCustomer(ICustomer c)
{
this.customer = c;
}
public string Nameinterface IClientCustomer
{
string Name { get; }
}public class ClientCustomer : IClientCustomerpublic ViewModel(ICustomerService svc)
{
this.svc = svc;
Customers = new List<IClientCustomer>();Context
StackExchange Code Review Q#82691, answer score: 5
Revisions (0)
No revisions yet.