WCF — реально мощная штука, но раз за разом для новых проектов мы вынуждены создавать новые, похожие друг на друга веб-сервисы. В этой статье (переводе) мы увидем, как создать повторно используемый веб-сервис с помощью Nelibur. Nelibur — это Message based web service framework на чистом WCF. Давайте посмотрим, как начать создание web-сервисов на WCF с использованием Nelibur.
Шаг 1. Создание приложения
Для простоты хостить WCF-сервис будет консольное приложение. Так что просто добавляем новый консольный проект.
Шаг 2. Инсталлируем Nelibur
Самый простой способ установить Nelibur — воспользоваться NuGet package manager.
То же самое можно сделать с помощью Package Manager Console
Теперь мы готовы создать RESTful WCF message based сервис.
Шаг 3. Создаем WCF-сервис
Для примера, возмем следующие требования к WCF-сервису:
- InstanceContextMode должен быть
PerCall
ResponseFormat
должен бытьJson
Nelibur уже содержит нужную нам реализацию: JsonServicePerCall.
Итак, добавляем код запуска нашего сервиса.
internal class Program
{
private static WebServiceHost _service;
private static void Main()
{
_service = new WebServiceHost(typeof(JsonServicePerCall));
_service.Open();
Console.WriteLine("ShipTrackingService is running");
Console.WriteLine("Press any key to exitn");
Console.ReadKey();
_service.Close();
}
}
Прописываем конфигурацию
<system.serviceModel>
<services>
<service name="Nelibur.ServiceModel.Services.Default.JsonServicePerCall">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9095/ShipTrackingService" />
</baseAddresses>
</host>
<endpoint binding="webHttpBinding"
contract="Nelibur.ServiceModel.Contracts.IJsonService" />
</service>
</services>
</system.serviceModel>
Реализуем бизнес-логику
Наш сервис должен уметь:
- Добавлять корабль
- Получать корабль по
ShipId
Создаем команду AddShipCommand
public sealed class AddShipCommand
{
public string ShipName { get; set; }
}
Результатом выполнения команды должен стать объект ShipInfo
public sealed class ShipInfo
{
public Guid Id { get; set; }
public string Name { get; set; }
}
Добавляем запрос ShipLocationQuery
, результатом выполнения которого должен быть объект ShipLocation
public sealed class ShipLocationQuery
{
public Guid ShipId { get; set; }
}
public sealed class ShipLocation
{
public string Location { get; set; }
public Guid ShipId { get; set; }
}
Теперь нам нужно сделать обработчик команды и запроса
public sealed class ShipProcessor : IPost<AddShipCommand>,
IGet<ShipLocationQuery>
{
private static readonly Dictionary<Guid, Ship> _ships = new Dictionary<Guid, Ship>();
public object Get(ShipLocationQuery request)
{
if (_ships.ContainsKey(request.ShipId))
{
return new ShipLocation
{
Location = "Sheldonopolis",
ShipId = request.ShipId
};
}
throw new WebFaultException(HttpStatusCode.BadRequest);
}
public object Post(AddShipCommand request)
{
var ship = new Ship(request.ShipName, Guid.NewGuid());
_ships[ship.Id] = ship;
return new ShipInfo
{
Id = ship.Id,
Name = ship.Name
};
}
}
Связываем команду и запрос с обработчиком
internal class Program
{
private static WebServiceHost _service;
private static void ConfigureService()
{
NeliburRestService.Configure(x =>
{
x.Bind<AddShipCommand, ShipProcessor>();
x.Bind<ShipLocationQuery, ShipProcessor>();
});
}
private static void Main()
{
ConfigureService();
_service = new WebServiceHost(typeof(JsonServicePerCall));
_service.Open();
Console.WriteLine("ShipTrackingService is running");
Console.WriteLine("Press any key to exitn");
Console.ReadKey();
_service.Close();
}
}
Все, сервис закончен. Как вы заметили, вы можете добавлять любые операции без изменения WCF-сервиса…
Клиент, использующий наш WCF-сервис
В качестве клиента можно использовать:
- Fiddler
- Rest Console — расширение Google chrome
- JsonServiceClient — клиент, встроенный в Nelibur
Fiddler
Добавление нового корабля (с помощью POST-запроса):
Получение корабля по ShipId (с помощью GET-запроса):
JsonServiceClient
Для создания своего клиента — добавляем еще одно консольное приложение.
Вот код клиента:
internal class Program
{
private static void Main()
{
var client = new JsonServiceClient(Settings.Default.ServiceAddress);
var shipInfo = client.Post<ShipInfo>(new AddShipCommand { ShipName = "Star" });
Console.WriteLine("The ship has added: {0}", shipInfo);
var shipLocation = client.Get<ShipLocation>(new ShipLocationQuery { ShipId = shipInfo.Id });
Console.WriteLine("The ship {0}", shipLocation);
Console.ReadKey();
}
}
Запускаем наш клиент и видим результат выполнения:
На стороне сервиса
На стороне клиента
Дополнительная литература
- What is a message based web service?
- Advantages of message based web services
- Построение RESTful Message Based веб-сервисов на WCF
Вот и все
Я надеюсь, вам понравилось. Спасибо за чтение статьи (перевода).
Исходники можно скачать с оригинала.
Автор: Truba