WCF рдФрд░ Nelibur рдкрд░ RESTful рд╡реЗрдм рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реБрдЖрдд рдХрд░рдирд╛

WCF рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рд╣реА рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЪреАрдЬ рд╣реИ, рд▓реЗрдХрд┐рди рдирдИ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рд╣рдо рдирдИ, рд╕рдорд╛рди рд╡реЗрдм рд╕реЗрд╡рд╛рдУрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рд╣реИрдВред рдЗрд╕ рд▓реЗрдЦ (рдЕрдиреБрд╡рд╛рдж) рдореЗрдВ рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдиреЗрд▓реАрдмреБрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдкреБрди: рдЙрдкрдпреЛрдЧ рдпреЛрдЧреНрдп рд╕рдВрджреЗрд╢ рдЖрдзрд╛рд░рд┐рдд рд╡реЗрдм рд╕реЗрд╡рд╛ рдХреИрд╕реЗ рдмрдирд╛рдИ рдЬрд╛рдП ред рдиреЗрд▓реАрдмреБрд░ рд╢реБрджреНрдз WCF рдкрд░ рдПрдХ рд╕рдВрджреЗрд╢ рдЖрдзрд╛рд░рд┐рдд рд╡реЗрдм рд╕реЗрд╡рд╛ рдврд╛рдВрдЪрд╛ рд╣реИред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдиреЗрд▓рд┐рдмреБрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбрдмреНрд▓реНрдпреВрд╕реАрдПрдл рдкрд░ рд╡реЗрдм рд╕реЗрд╡рд╛рдУрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХреИрд╕реЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рдПред



рдЪрд░рдг 1. рдПрдХ рдЖрд╡реЗрджрди рдмрдирд╛рдПрдБ



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





рдЪрд░рдг 2. рдиреЗрд▓рд┐рдмреБрд░ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ



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





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





рдЕрдм рд╣рдо рдПрдХ RESTful WCF рд╕рдВрджреЗрд╢ рдЖрдзрд╛рд░рд┐рдд рд╕реЗрд╡рд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВред



рдЪрд░рдг 3. рдПрдХ WCF рд╕реЗрд╡рд╛ рдмрдирд╛рдПрдБ



рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо WCF рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рд▓реЗрддреЗ рд╣реИрдВ:



рдиреЗрд▓реАрдмреБрд░ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд╛рдЧреВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: 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>
      
      







рд╣рдо рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ



рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:



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 рд╕реЗрд╡рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдЧреНрд░рд╛рд╣рдХ



рдПрдХ рдЧреНрд░рд╛рд╣рдХ рдХреЗ рд░реВрдк рдореЗрдВ, рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:



рд╕рд╛рд░рдВрдЧреА рдмрдЬрд╛рдиреЗрд╡рд╛рд▓рд╛



рдПрдХ рдирдпрд╛ рдЬрд╣рд╛рдЬ рдЬреЛрдбрд╝рдирд╛ (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(); } }
      
      





рд╣рдо рдЕрдкрдиреЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд▓реЙрдиреНрдЪ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджреЗрдЦрддреЗ рд╣реИрдВ:



рд╕реЗрд╡рд╛ рдХреА рддрд░рдл





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





рдЖрдЧреЗ рдкрдврд╝ рд░рд╣реЗ рд╣реИрдВ







рд╡рд╣ рд╕рдм



рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдЕрдЪреНрдЫрд╛ рд▓рдЧрд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдЦ (рдЕрдиреБрд╡рд╛рдж) рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

рдореВрд▓ рд╕реЗ рд╕реНрд░реЛрдд рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред



рдЕрдиреБрд╡рд╛рджрдХ рд╕реЗ



рд▓реЗрдЦ рдкрдврд╝рддреЗ рд╕рдордп, рдореИрдВ рдЕрдиреБрд░реЛрдзреЛрдВ рдФрд░ рд╣реИрдВрдбрд▓рд░ рдХреЗ рдПрдХ рд╕рдореВрд╣ рдХреЗ рдХреЛрдб рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ:

  private static void ConfigureService() { NeliburRestService.Configure(x => { x.Bind<AddShipCommand, ShipProcessor>(); x.Bind<ShipLocationQuery, ShipProcessor>(); }); }
      
      





рд╕реЗрд╡рд╛ рдореЗрдВ рдирдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдЕрдиреБрд░реЛрдз / рдХрдорд╛рдВрдб рдХреНрд▓рд╛рд╕, рд╣реИрдВрдбрд▓рд░ рдХреНрд▓рд╛рд╕ рдФрд░ рдЙрдирдХреЗ рдмрдВрдбрд▓ рдмрдирд╛рдиреЗ рдореЗрдВ рдХрдореА рдЖрдПрдЧреАред рдЖрд╕рд╛рдиреА рд╕реЗ рдФрд░ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕рдВрдЧрдард┐рдд рдФрд░ рдкреНрдпрд╛рд░рд╛ рджрд┐рд▓ CQRS рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ред рдиреЗрд▓реАрдмреБрд░ рдЖрдкрдХреЛ рдиреНрдпреВрдирддрдо рд╢реНрд░рдо рдХреЗ рд╕рд╛рде рдЗрд╕ рдЪрдорддреНрдХрд╛рд░ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдФрд░ рдЕрдЧрд░ рдЖрдк рдереЛрдбрд╝рд╛ рд╕рдордЭрджрд╛рд░ рд╣реИрдВ, рддреЛ рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ \ рдХрдорд╛рдВрдб рдФрд░ рд╣реИрдВрдбрд▓рд░реНрд╕ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдЕрдкрдиреЗ рдЖрдк рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдЬрд╛рджреВ рдкреВрд░рд╛ рд╣реЛ рдЬрд╛рдПрдЧрд╛ :)



All Articles