Как создать расширяемый сервис WCF
Мне нужен сервис, который будет вызываться из моего клиентского проекта. Требование состоит в том, что я могу изменить и освободить службу, но после изменения службы не должно быть необходимости перестраивать клиента. Например, предположим, у меня есть служба, которая помогает человеку добраться до пункта назначения
[ServiceContract]
IDestinationHelper
{
[OperationContract]
void ReachDestination(string person);
}
class ReachedByTrain:IDetinationHelper
{
void ReachDestination(string person)
{
//Help the person to reach destination
}
}
Теперь служба помогает человеку добраться до пункта назначения поездом, в этом случае я буду звонить в службу ReachedByTrain от клиента, но предположим, что есть требование, и я хочу, чтобы человек достиг рейсом, в таком случае, как мне действовать без изменение или построение клиента. Функциональность должна быть подключаемой, и клиент должен автоматически обнаруживать ее
class ReachedByFlight:IDetinationHelper
{
void ReachDestination(string person)
{
//Help the person to reach destination
}
}
Пожалуйста, предоставьте любую помощь или ссылку о том, как это можно сделать.
PS За один раз клиенту будет представлен только один режим. Неважно, если клиент не знает об этом.
2 ответа
У вас есть несколько способов достижения расширяемости.
Интерфейс исправлен в вашем клиенте. Создание кода, который обрабатывает изменяющийся интерфейс, сложно и подвержено ошибкам. Не делай этого.
Таким образом, вам нужно будет сохранить интерфейс без изменений и изменить внутреннее поведение вашего класса.
В вашем примере ваша служба может вернуть список точек в виде маршрута к цели и строку, в которой указан режим транспортировки. Теперь вы можете включать все виды видов транспорта и маршруты возврата для них без изменения интерфейса.
Когда вы добавляете новый возможный режим транспортировки, клиент должен быть уведомлен, чтобы он мог быть представлен пользователю, например, в ComboBox. Это означает, что вам нужен метод в вашем интерфейсе, который возвращает все возможные виды транспорта. Таким образом, ваш клиент может обрабатывать новые без перекомпиляции. Он даже может справиться с этим при удалении режимов.
Таким образом, у вашего клиента есть контракт, и контракт никогда не меняется. Но ваши методы могут возвращать разные вещи при перестроении и повторном развертывании службы.
Пример:
Этот контракт никогда не меняется:
[ServiceContract]
IDestinationHelper
{
[OperationContract]
IEnumerable<Waypoint> ReachDestination(string transportationMode);
[OperationContract]
IEnumerable<string> GetAvailabletransportationModes();
}
IDestinationHelperService : IDestinationHelper
{
public IEnumerable<Waypoint> ReachDestination(string transportationMode)
{
// decide return value by transportation mode. Use a switch statement, dependency injection, IoC containers, whatever you want
}
public IEnumerable<string> GetAvailabletransportationModes()
{
// decide return value by getting all modes from wherever you decided upon above.
}
}
Я думаю, что вам нужно иметь [ServiceContract] с [OperationContract], который будет принимать "ModeOfTransport" в качестве параметра и иметь логику маршрутизации для создания объекта ReachByTrain или ReachByPlane или ReachByAnything и вызывать его из [OperationContract], Со стороны клиента вы можете вызвать [OperationContract], который имеет логику маршрутизации с соответствующим параметром под рукой.