Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
436 views
in Technique[技术] by (71.8m points)

c# - Dynamic Namespace Switching

I'm attempting to put a web service wrapper around several third-party web services. For the sake of this question, we'll work with two of them:

  1. OrderService
  2. AddressService

Both of these services have the same object defined in different namespaces:

  1. OrderService.AuthenticationParameters
  2. AddressService.AuthenticationParameters

I was hoping to be able to create a single base class that would be able to detect/switch between namespaces. For example:

public abstract class BaseLogic
{
    internal BaseLogic()
    {
        /* Initialize authParams */

        //Switch out / detect namespace here
        this.authParams = new OrderService.AuthenticationParameters();
        this.authParams.accountName = "[MyAccountName]";
        this.authParams.userName = "[MyUserName]";
        this.authParams.password = "[MyPassword]";
    }
}

I've seen several similar questions. Either they don't apply to my situation, or I'm incapable of understanding them.

Question: Is what I'm trying to achieve possible? If it's possible, am I over complicating things?

Additional Info: Eventally, there will be more than two services that share this common object. The vendor provides a separate service URL for each branch of functionality they provide.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are quite a few solutions to this.

  • Have your service proxy classes implement your own interface to expose the methods, and then simply use reflection to build a type.
  • Wrap both services in another class that exposes the methods and has a reference to both services, then simply provide a switching argument to determine which to use.
  • Abstract the use of a service via your own interface and have classes coded against each service explicitly (see below).

Or if you want to play with dynamic and duck typing, this seemed to work:

namespace ConsoleApplication42
{
    class Program
    {
        static void Main(string[] args)
        {
            Type t1 = Type.GetType("ProviderOne.AuthService");

            dynamic service = Activator.CreateInstance(t1);

            Console.WriteLine(service.GetUsername());

            Type t2 = Type.GetType("ProviderTwo.AuthService");

            service = Activator.CreateInstance(t2);
            Console.WriteLine(service.GetUsername());

            Console.Read();
        }
    }
}

namespace ProviderOne
{
    public class AuthService
    {
        public string GetUsername()
        {
            return "Adam";
        }
    }
}

namespace ProviderTwo
{
    public class AuthService
    {
        public string GetUsername()
        {
            return "Houldsworth";
        }
    }
}

Bear in mind they all hinge on both services having the same signature.

As for the other services in future, it really depends. I've never really encountered a need to dynamically switch from one service to another to get slightly different behaviour in achieving the same thing.

Perhaps this should be driven from your app's side? Instead of a service being chosen to suit, simply implement two versions of the class that has this changing behaviour - put a common interface on it, and decide which of your classes to use at runtime. The class itself will then be coded directly against one of the services.

interface IGetUsername
{
    string GetUsername();
}

class UsernameViaProviderOne : IGetUsername
{
    public string GetUsername()
    {
        return new ProviderOne.AuthService().GetUsername();
    }
}

class UsernameViaProviderTwo : IGetUsername
{
    public string GetUsername()
    {
        return new ProviderTwo.AuthService().GetUsername();
    }
}

Then the decision is firmly in your client code and removes the need for reflection/dynamic typing:

IGetUsername usernameProvider = null;

if (UseProviderOne)
    usernameProvider = new UsernameViaProviderOne();

...

To labour the point, you could always get very SOA and create yet another service that your app talks to that aggregates the other two services. Then at least your client code doesn't see the huge number of different services and talks to just one.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...