рдЪрд░рдг 1. рдПрдХ рдЖрд╡реЗрджрди рдмрдирд╛рдПрдБ
рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, WCF рд╕реЗрд╡рд╛ рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╣реЛрд╕реНрдЯ рдХрд░реЗрдЧреАред рддреЛ рдмрд╕ рдПрдХ рдирдпрд╛ рдХрдВрд╕реЛрд▓ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдЬреЛрдбрд╝реЗрдВред

рдЪрд░рдг 2. рдиреЗрд▓рд┐рдмреБрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ
рдирд╛рд▓рд┐рдмреБрд░ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ NuGet рдкреИрдХреЗрдЬ рдореИрдиреЗрдЬрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред

рдЖрдк рдкреИрдХреЗрдЬ рдореИрдиреЗрдЬрд░ рдХрдВрд╕реЛрд▓ рдХреЗ рд╕рд╛рде рднреА рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

рдЕрдм рд╣рдо рдПрдХ RESTful WCF рд╕рдВрджреЗрд╢ рдЖрдзрд╛рд░рд┐рдд рд╕реЗрд╡рд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВред
рдЪрд░рдг 3. рдПрдХ WCF рд╕реЗрд╡рд╛ рдмрдирд╛рдПрдБ
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо WCF рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рд▓реЗрддреЗ рд╣реИрдВ:
- InstanceContextMode
PerCall
рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП -
ResponseFormat
Json
рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
рдиреЗрд▓реАрдмреБрд░ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд╛рдЧреВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: 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 exit\n"); 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 exit\n"); Console.ReadKey(); _service.Close(); } }
рд╕рдм рдХреБрдЫ, рд╕реЗрд╡рд╛ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдИ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдиреЗ рджреЗрдЦрд╛, рдЖрдк WCF рд╕реЗрд╡рд╛ рдХреЛ рдмрджрд▓реЗ рдмрд┐рдирд╛ рдХреЛрдИ рднреА рдСрдкрд░реЗрд╢рди рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ ...
рд╣рдорд╛рд░реА WCF рд╕реЗрд╡рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдЧреНрд░рд╛рд╣рдХ
рдПрдХ рдЧреНрд░рд╛рд╣рдХ рдХреЗ рд░реВрдк рдореЗрдВ, рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
- рд╕рд╛рд░рдВрдЧреА рдмрдЬрд╛рдиреЗрд╡рд╛рд▓рд╛
- рдмрд╛рдХреА рдХрдВрд╕реЛрд▓ - Google Chrome рдПрдХреНрд╕рдЯреЗрдВрд╢рди
- JsonServiceClient - рдПрдХ рдЧреНрд░рд╛рд╣рдХ Nelibur рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ
рд╕рд╛рд░рдВрдЧреА рдмрдЬрд╛рдиреЗрд╡рд╛рд▓рд╛
рдПрдХ рдирдпрд╛ рдЬрд╣рд╛рдЬ рдЬреЛрдбрд╝рдирд╛ (POST рдЕрдиреБрд░реЛрдз рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛):

рд╢рд┐рдкрдЖрдИрдбреА рджреНрд╡рд╛рд░рд╛ рдЬрд╣рд╛рдЬ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ (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(); } }
рд╣рдо рдЕрдкрдиреЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд▓реЙрдиреНрдЪ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджреЗрдЦрддреЗ рд╣реИрдВ:
рд╕реЗрд╡рд╛ рдХреА рддрд░рдл

рдЧреНрд░рд╛рд╣рдХ рдкрдХреНрд╖

рдЖрдЧреЗ рдкрдврд╝ рд░рд╣реЗ рд╣реИрдВ
- рд╕рдВрджреЗрд╢ рдЖрдзрд╛рд░рд┐рдд рд╡реЗрдм рд╕реЗрд╡рд╛ рдХреНрдпрд╛ рд╣реИ?
- рд╕рдВрджреЗрд╢ рдЖрдзрд╛рд░рд┐рдд рд╡реЗрдм рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд╛рдн
- WCF рдкрд░ рдкреНрд░рддрд┐рд╖реНрдард┐рдд рд╕рдВрджреЗрд╢ рдЖрдзрд╛рд░рд┐рдд рд╡реЗрдм рд╕реЗрд╡рд╛рдУрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг
рд╡рд╣ рд╕рдм
рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдЕрдЪреНрдЫрд╛ рд▓рдЧрд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдЦ (рдЕрдиреБрд╡рд╛рдж) рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред
рдореВрд▓ рд╕реЗ рд╕реНрд░реЛрдд рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдЕрдиреБрд╡рд╛рджрдХ рд╕реЗ
рд▓реЗрдЦ рдкрдврд╝рддреЗ рд╕рдордп, рдореИрдВ рдЕрдиреБрд░реЛрдзреЛрдВ рдФрд░ рд╣реИрдВрдбрд▓рд░ рдХреЗ рдПрдХ рд╕рдореВрд╣ рдХреЗ рдХреЛрдб рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ:
private static void ConfigureService() { NeliburRestService.Configure(x => { x.Bind<AddShipCommand, ShipProcessor>(); x.Bind<ShipLocationQuery, ShipProcessor>(); }); }
рд╕реЗрд╡рд╛ рдореЗрдВ рдирдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдЕрдиреБрд░реЛрдз / рдХрдорд╛рдВрдб рдХреНрд▓рд╛рд╕, рд╣реИрдВрдбрд▓рд░ рдХреНрд▓рд╛рд╕ рдФрд░ рдЙрдирдХреЗ рдмрдВрдбрд▓ рдмрдирд╛рдиреЗ рдореЗрдВ рдХрдореА рдЖрдПрдЧреАред рдЖрд╕рд╛рдиреА рд╕реЗ рдФрд░ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕рдВрдЧрдард┐рдд рдФрд░ рдкреНрдпрд╛рд░рд╛ рджрд┐рд▓ CQRS рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ред рдиреЗрд▓реАрдмреБрд░ рдЖрдкрдХреЛ рдиреНрдпреВрдирддрдо рд╢реНрд░рдо рдХреЗ рд╕рд╛рде рдЗрд╕ рдЪрдорддреНрдХрд╛рд░ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдФрд░ рдЕрдЧрд░ рдЖрдк рдереЛрдбрд╝рд╛ рд╕рдордЭрджрд╛рд░ рд╣реИрдВ, рддреЛ рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ \ рдХрдорд╛рдВрдб рдФрд░ рд╣реИрдВрдбрд▓рд░реНрд╕ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдЕрдкрдиреЗ рдЖрдк рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдЬрд╛рджреВ рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рдПрдЧрд╛ :)