开发者

Wrapping an API to support dependency injection

I am interacting with an API that just has static functions, and cannot be opened up and changed.

    public class WindowsNativeGraphAPI
    {
        public static IEnumerable<IGraphData> GetGraphData();
        public static bool DeleteGraphData(IGraphData data);
    }

I would like to be able to pass the API into a function or constructor and comply with dependency injection (just in case we were to swap out the API later).

public void GatherGraphData(IGraphAPI api)
{...}

To allow this API to be passed in as a parameter, I'd need to at least abstract to 开发者_运维百科use an interface to pass into the function.

    public interface IGraphAPI
    {
        IEnumerable<IGraphData> GetGraphData();
        bool DeleteGraphData(IGraphData data);
    }

However, I would then need to implement the interface in another class as I cannot change the original API. This class would be a lightweight wrapper around the API that just invokes the corresponding function on the API and returns the same result.

    public class WindowsGraphAPI : IGraphAPI
    {
        public IEnumerable<IGraphData> GetGraphData()
        {
            return WindowsNativeGraphAPI.GetGraphData();
        }

        public bool DeleteGraphData(IGraphData data)
        {
            return WindowsNativeGraphAPI.DeleteGraphData(data)
        }
    }

I don't like the idea of creating another class to wrap the API. I understand that this wrapper would be very lightweight and would just return the results of the API, but how do I test the wrapper? The wrapper should probably also contain some exception handling to cope with errors in the API. If we were to change to another API, that suffered the same problem, we'd have to create these extra classes and interfaces again.

Ideally, the end result would be a mockable API that can be used when writing the unit tests for the new component that consumes it.

Is this the proper way to do this? Can it be done another way?

Thanks


Yes, it's the proper way. The new API interface and proxy class encapsulate the decision of what underlying library to use - a single responsibility.


Yes that is the proper way. I would not put exception handling in your wrapper, all you are doing is creating a class that calls static methods so you can use DI. You want the wrapper to cause the same exceptions under the same circumstances as the API class with the static methods. That way you can use the same exception handling in your method as you would if you were called the class with the static methods. You can then throw the same exceptions under the same circumstances in your mock api class and test the excpetion handling.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜