开发者

Help Creating an Interface

I'm starting to see the value of Interfaces vs. lets say an Abstract class.

Currently I'm working on a PayPal Wrapper project. We'll also be probably doing a Google Payments, BillMeLater, and Amazon wrapper. I've been asked to identify some commonalities (methods, properties, whatever) that we could use across the board, in most any Web Service SOAP Wsdl Wrapper开发者_StackOverflow project for any web services we do.

So as I was coding out my PayPal wrappers, I created a new class to hold Errors received back from any PayPal response:

public class ApiError
{

    #region Constructors

    /// <summary>
    /// Disallow default instantiation.
    /// </summary>
    private ApiError()
    {
    }

    internal ApiError(ErrorType error)
    {
        if(error.ErrorCode != null)
        {
            this._errorCode = error.ErrorCode;
        }
    }

    #endregion

    #region member variables

    private string _errorCode = string.Empty;
    private string _erorMessage = string.Empty;

    #endregion

    #region Properties

    public string ErrorCode
    {
        get { return _errorCode; }
        set { _errorCode = value; }
    }

    public string ErrorMessage
    {
        get { return _errorMessage; }
        set { _errorMessage = value; }
    }

    #endregion

}

Anyway, I said hey, these ErrorMessage and ErrorCode properties are most likely going to be in every third party API. So why not create an Interface in a new project called [MyCompany].WebServices.Common and in that interface add those 2 properties. Then any class wrapper that I create that has functionality to make API proxy calls can implement this interface and then I know any of those kinds of wrapper classes in any of our web service projects will be guaranteed to have these kind of properties in them that will be impolemented and filled with any errors that come back from an API response.

And if they do, then that's great because I can then start to create some helper methods that we can use across the board if I can somehow take in a generic response object and fill the array of errors and set the property.

Anyway, my problem is, I'm new to interfaces a litte. So the error array property from above for example is of a custom type.

Well if I create interface in a seperate physical project, I can't use that custom type because it doesn't exist..it only exists so far in my PayPal wrapper project.

So then when stubbing this interface out, how would I handle this?

namespace [MyCompany].WebServices.Common
{
    interface IRequest
    {

        public ApiError Type { get; set; } //whoops, that's a custom type that this project does not know about (ApiError)
    }

}


You should consider that the ApiErrors are going to depend on the particular web service implementation. So how would a client that is using only interfaces going to use the ApiErrors if they are implementation-specific?

It can't - because this would mean that its coupled to this particular implementation.

Instead, you need to abstract away from the specific API error codes, and define your own abstract error codes.


Every Problem in Software can be Solved with Another Layer of Indirection!!! Just add another interface called IAPIError that you implement for each pay service error type.

interface IRequest
{
   public IApiError Type { get; set; } 
}


You could put your shared types in a separate, shared assembly: [MyCompany].WebServices.Shared

Edit
Come to think of it, you already have that. [MyCompany].WebServices.Common should be as good a place as any for your shared types. Just move it there. Or am I misunderstanding what you want to do?


The exact error numbers and messages will be very specific for each provider. Therefore, while a common interface can be made, it will not provide enough abstraction to handle errors in a meaningful way.

I'd add another abstraction by defining the expected errors (one of which is "unknown error" as catch-all for unexpected errors) as separate class or even as set of Exceptions. Then, have each provider return or use those, which is already compatible with your application and allows you to handle common errors for all providers the same way.

Put those common types into a separate assembly, which is a pure "interface" assembly used by both the providers and the actual code using them. Therefore you'll be able to loosely couple the providers without having to add references to them in your main application (allowing you to add or modify providers without recompiling the application).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜