我正在尝试将Web服务包装器放在几个第三方Web服务上。为了这个问题,我们将与其中两个合作:
这两个服务都具有在不同名称空间中定义的相同对象:
我希望能够创建一个能够在名称空间之间检测/切换的基类。例如:
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]";
}
}
我见过几个类似的问题。要么它们不适用于我的情况,要么我无法理解它们。
问题:我正在尝试实现的目标是什么?如果有可能,我是否过于复杂化了?
其他信息:最终,将有两个以上的服务共享此公共对象。供应商为他们提供的每个功能分支提供单独的服务URL。
答案 0 :(得分:3)
这方面有很多解决方案。
或者如果你想玩动态和鸭子打字,这似乎有效:
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";
}
}
}
请记住,他们都依赖于具有相同签名的两项服务。
至于未来的其他服务,实际上取决于。我从来没有真正遇到过从一个服务动态切换到另一个服务的需要,以便在实现同样的事情时获得稍微不同的行为。
也许这应该来自你的应用程序?而不是选择适合的服务,只需实现具有这种变化行为的类的两个版本 - 在其上放置一个通用接口,并决定 您的 类中的哪一个在运行时使用。然后,类本身将直接针对一个服务进行编码。
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();
}
}
然后,决定是坚定地在您的客户端代码中,并消除了反射/动态类型的需要:
IGetUsername usernameProvider = null;
if (UseProviderOne)
usernameProvider = new UsernameViaProviderOne();
...
为了解决这个问题,您可以随时获得非常SOA并创建另一项服务,您的应用会与之交谈,从而聚合其他两项服务。然后,至少你的客户端代码没有看到大量不同的服务,只与一个人进行对话。
答案 1 :(得分:0)
嗯,我唯一能想到的就是使用反射来创建对象。问题是你必须再次使用反射来设置属性,调用方法等,因为我猜你没有共享接口。虽然它的大量工作可能会降低性能,但它确实可以解决问题。 查看带有Activator的CreateInstance,您可以传递完整的合格类名称并创建实例。 然后,使用此新创建对象的类型,您可以搜索要修改的属性。
答案 2 :(得分:-2)
您可以使用#if。
#if true
using MyService.X;
using x=MyService.A;
#endif
#if false
using MyService2.X;
using x=MyService.B;
#endif
但是你无法改变运行时间,因为它适用于编译时。
注意:不是一个好的编程习惯。但这存在。