我在使用N个提供程序发送SMS消息的Web服务中工作。每个提供者都在其自己的Web服务上以不同的格式接收消息。
为了在我的Web服务中创建模式,我创建了一个抽象类,其中包含许多要为每个提供程序实现的方法。
某些方法需要接收一个可以具有不同类型的对象,具体取决于继承该对象的子类(提供者)。这些方法之一返回的对象可以是至少两种不同的类型。
我通过“ object”关键字实现了此目的,该关键字使我可以传递或返回任何对象:
public abstract class Provider {
protected HttpClient _Client;
protected SMSManagerAPIContext _Context;
public abstract DeliveryResponse SendSMS(object Sms);
protected abstract DeliveryResponse ParseResponse(HttpResponseMessage Response);
public abstract object PrepareMessage(SMS Sms);
protected abstract void SaveResponse(object Sms, HttpResponseMessage Response);
}
在Sms
方法中接收到的对象SendSMS
是PrepareMessage
方法的返回。问题是PrepareMessage
可能返回不同类型的对象。
(例如,我的一个提供程序接受了发送一条或多条消息的请求,但是每个对象的对象都不同。然后,我在PrepareMessage
方法中返回正确的对象,而在{{1 }}方法将其作为JSON对象发送给提供程序。)
它可以工作,但是在开发过程中会在子类中引起一些转换问题,我想知道是否有更好的方法可以做到这一点。 我已经阅读了有关此问题的一些信息:
Generic method that can return different types
我认为使用泛型的重载方法会更好,但是我没有C#的经验。
有什么想法吗?
答案 0 :(得分:1)
我认为您是正确的,听起来确实是使用泛型的好地方,也许像这样,“ T”(按惯例称为t)就是您使用的类型。
public abstract class Provider<T>
{
protected HttpClient _Client;
protected SMSManagerAPIContext _Context;
public abstract DeliveryResponse SendSMS(T Sms);
protected abstract DeliveryResponse ParseResponse(HttpResponseMessage Response);
public abstract T PrepareMessage(SMS Sms);
protected abstract void SaveResponse(object Sms, HttpResponseMessage Response);
}
public class SMS {
public string Message { get; set; }
}
public class SMSManagerAPIContext{}
public class DeliveryResponse { }
public class PremiumSMS
{
public double Cost { get; set; }
public string Message { get; set; }
}
public class PremiumSmsProvider : Provider<PremiumSMS>
{
public const double Cost = 3.99;
public override PremiumSMS PrepareMessage(SMS Sms)
{
return new PremiumSMS {
Message = Sms.Message,
Cost = Cost
};
}
public override DeliveryResponse SendSMS(PremiumSMS Sms)
{
throw new NotImplementedException();
}
protected override DeliveryResponse ParseResponse(HttpResponseMessage Response)
{
throw new NotImplementedException();
}
protected override void SaveResponse(object Sms, HttpResponseMessage Response)
{
throw new NotImplementedException();
}
}
public class FreeSMS
{
public string Message { get; set; }
}
public class FreeSmsProvider : Provider<FreeSMS>
{
public override FreeSMS PrepareMessage(SMS Sms)
{
return new FreeSMS{
Message = Sms.Message
};
}
public override DeliveryResponse SendSMS(FreeSMS Sms)
{
throw new NotImplementedException();
}
protected override DeliveryResponse ParseResponse(HttpResponseMessage Response)
{
throw new NotImplementedException();
}
protected override void SaveResponse(object Sms, HttpResponseMessage Response)
{
throw new NotImplementedException();
}
}
有关泛型类的更多信息:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generic-classes
答案 1 :(得分:1)
使用工厂。使用此代码的代码可能只关心将字符串消息发送给某个电话号码,并获取该消息是否成功,如果失败则返回错误消息。
创建消息本身以遵守不同的提供者/实现应该只是在一个黑框中。不同的提供程序将具有不同的构造函数。
public interface ISmsProvider
{
(bool, string) SendMessage(string number, string message);
}
public class SampleSmsProvider1 : ISmsProvider
{
public SampleSmsProvider1(string userKey, string passKey)
{
// initialize
}
public (bool, string) SendMessage(string number, string message)
{
// send the message (using a provider implementation from NuGet perhaps)
// return success/fail and error message, if applicable
return (true, string.Empty);
}
}
public class SmsFactory
{
public ISmsProvider GetProvider()
{
// Initialize and return one of the ISmsProvider implementations, depending on (I guess) the configuration
}
}