Я разрабатываю ряд 'сервисных' расположенных на слое объектов (объекты данных и интерфейсные определения) для веб-сервиса WCF (который будет использован сторонними клиентами т.е. не внутренний, так вне моего прямого управления).
Я знаю, что не собираюсь получать интерфейсное определение, точно правильное - и желаю подготовиться в течение времени, когда я знаю, что должен буду представить повреждающийся набор новых объектов данных. Однако действительность мира, в котором я нахожусь, - то, что я должен буду также выполнить свою первую версию одновременно долгое время.
Первая версия моего сервиса будет иметь URL http://host/app/v1service.svc
и то, когда время настает новой версией, будет жить по http://host/app/v2service.svc
Однако когда дело доходит до объектов данных и интерфейсов, я играю с помещением 'главной' версии интерфейсного числа в фактическое пространство имен классов.
namespace Company.Product.V1
{
[DataContract(Namespace = "company-product-v1")]
public class Widget
{
[DataMember]
string widgetName;
}
public interface IFunction
{
Widget GetWidgetData(int code);
}
}
Когда время настанет для коренного изменения в службу, я представлю некоторые классы как
namespace Company.Product.V2
{
[DataContract(Namespace = "company-product-v2")]
public class Widget
{
[DataMember]
int widgetCode;
[DataMember]
int widgetExpiry;
}
public interface IFunction
{
Widget GetWidgetData(int code);
}
}
Преимущества, поскольку я вижу его, состоят в том, что я смогу иметь единственный набор кода, служащего обеим версиям интерфейса, совместно используя функциональность, если это возможно. Это вызвано тем, что я смогу сослаться на обе версии интерфейса как на отличный набор объектов C#. Точно так же клиенты могут использовать обе версии интерфейса одновременно, возможно, с помощью V1. Виджет в некотором унаследованном коде, пока новые биты идут дальше к V2. Виджет.
Кто-либо может сказать, почему это - глупая идея? У меня есть нытье, чувствуя, что это является немного вонючим..
примечания: Я, очевидно, не предлагаю, чтобы каждая новая версия сервиса была бы в новом пространстве имен. По-видимому, я сделаю как можно больше неразрывных интерфейсных изменений, но я знаю, что поражу точку, где для всего моделирования данных, вероятно, будет нужно значительное, переписывают.
Я понимаю управление версиями блока и т.д., но я думаю, что этот вопрос является тангенциальным к тому типу управления версиями. Но я мог быть неправым.
Я сделал это так, как у вас (с пространствами имен V1
, V2
и пространством имен Common
), и это работает довольно хорошо. По сути, у меня есть фактический код, реализованный в пространстве имен Common
, и каждый из V1
, V2
и т.д. просто действует как обертка вокруг него.
В нашем случае старые версии, как правило, остаются надолго. Обычно, когда клиент запрашивает доступ к нашему API, мы даем ему "текущую" версию на тот момент, и затем он просто использует ее всегда - если только нет серьезного бизнес-причина для перехода на более новую версию, тогда они практически никогда этого не делают.
Обычно я видел (и делал сам) просто называя версию 2 Widget2, IWidget2 и т.д. Если вы ожидаете, что v2 (вероятно) будет конечной версией, основываясь на уроках, полученных при использовании v1 в дикой природе, то это обычно нормально. Но если вы ожидаете, что она будет постоянно развиваться, возможно, стоит подумать о более гибком подходе к контрактам.