{"id":379257,"date":"2024-06-20T03:00:14","date_gmt":"2024-06-20T03:00:14","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=379257"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=379257","title":{"rendered":"<span>\u041a\u043b\u044f\u0442\u0432\u0430 \u043d\u0430 \u043a\u0440\u043e\u0432\u0438: \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u0441 Pact \u0432 .NET. \u0427\u0430\u0441\u0442\u044c \u0432\u0442\u043e\u0440\u0430\u044f<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/articles\/823080\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u0442\u0435\u043c\u044b \u0431\u044b\u043b\u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u0442\u0435\u043e\u0440\u0438\u044f \u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043f\u043e HTTP. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u043d\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0439, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043c\u0441\u044f \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c PactBroker.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e06\/289\/721\/e06289721ac00589434e8956da27aad1.png\" width=\"1092\" height=\"614\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e06\/289\/721\/e06289721ac00589434e8956da27aad1.png\"\/><\/figure>\n<p>\u041d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 RabbitMq \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430. \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0441\u043f\u0438\u0441\u043e\u043a \u043c\u043e\u0436\u0435\u0442 \u0441\u0438\u043b\u044c\u043d\u043e \u0432\u0430\u0440\u044c\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f:<\/p>\n<ul>\n<li>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u0444\u043e\u0440\u043c\u0430\u0442)<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u0442\u0438\u043f \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0440\u043e\u0434\u0435 routing key, topics, reply-to \u0438 \u0442.\u0434. <\/p>\n<\/li>\n<\/ul>\n<h4>\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b \u0434\u043b\u044f \u0434\u0435\u043c\u043e<\/h4>\n<ul>\n<li>\n<p>.NET, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Pact \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 .netstandart2.0, \u0434\u0435\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 .NET 6;<\/p>\n<\/li>\n<li>\n<p>PactNet 5.0.0-beta.2 \u0438 PactNet.Abstractions 5.0.0-beta.2 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432; \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0440\u0435\u043b\u0438\u0437\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u043b\u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0432\u0435\u0440\u0441\u0438\u0438 4.5.0<a href=\"https:\/\/github.com\/pact-foundation\/pact-net\/issues\/468\" rel=\"noopener noreferrer nofollow\"> <u>\u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 non-ASCII \u0441\u0438\u043c\u0432\u043e\u043b\u044b<\/u><\/a>. \u0422\u0430\u043a\u0436\u0435, \u0434\u043e 5.x.x \u0432\u0435\u0440\u0441\u0438\u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f Newthonsoft.Json \u0432\u043c\u0435\u0441\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e System.Text.Json;<\/p>\n<\/li>\n<li>\n<p>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 EasyNetQ 7.8.0 \u0438 EasyNetQ.Serialization.SystemTextJson 7.8.0 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 RabbitMq;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u0435\u0440 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 RabbitMq \u0438 PactBroker.<\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u043d\u043e\u0441\u0438\u0442 \u043b\u0438\u0448\u044c \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440 \u0434\u043b\u044f \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b PactNet \u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043e\u0431\u0438\u0435\u043c \u043f\u043e \u0447\u0438\u0441\u0442\u043e\u043c\u0443 \u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u043a\u043e\u0434\u0443. \u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u0434\u0435\u043c\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432<a href=\"https:\/\/github.com\/niyazz\/PactContractTestingDemo\/tree\/main\" rel=\"noopener noreferrer nofollow\"> <u>\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/u><\/a>.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438<\/h3>\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c RabbitMq \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043e \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u0440\u0442\u044b. \u0422\u0430\u043a, \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 (Demo.Provider) \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u0441 \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0443. \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c (Demo.Consumer) \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044f <code>ShouldBeNotified<\/code>, \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u043d\u0430 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0431\u044b\u043b\u0438 \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438:<\/p>\n<ul>\n<li>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u043e\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <code>CardOrderSatisfiedEvent<\/code> \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442: \u043a\u043e\u0434 \u043a\u0430\u0440\u0442\u044b-\u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430, \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0440\u0438\u0437\u043d\u0430\u043a \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u0430 SpecialExchangeName, \u0442\u0438\u043f direct;<\/p>\n<\/li>\n<li>\n<p>Routing-key \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 super-routing-key.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u0441\u0431\u043e\u0440\u043a\u0438 Consumer.Host \u0438 Provider.Host \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"xml\"> &lt;PackageReference Include=\"EasyNetQ\" Version=\"7.8.0\" \/>  &lt;PackageReference Include=\"EasyNetQ.Serialization.SystemTextJson\" Version=\"7.8.0\" \/><\/code><\/pre>\n<p>\u0421 \u0446\u0435\u043b\u044c\u044e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 Demo.Provider:  <\/p>\n<pre><code class=\"cs\">[HttpPost(\"order-satisfied\/{userId}\")] public async Task&lt;ActionResult> SendCardOrderSatisfiedEvent(string userId) {     var advancedBus = RabbitHutch.CreateBus(\"host=localhost\", s =>     {         s.EnableConsoleLogger();         s.EnableSystemTextJson();     }).Advanced;     var exchange = await advancedBus                         .ExchangeDeclareAsync(\"SpecialExchangeName\", \"direct\");     var message = new Message&lt;CardOrderSatisfiedEvent>(           new CardOrderSatisfiedEvent           {             UserId = userId,             CardCode = Random.Shared.Next(100)           });     await advancedBus.PublishAsync(exchange, \"super-routing-key\", false, message);     return Ok(); } <\/code><\/pre>\n<p>\u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 Program, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0433\u0434\u0435-\u043d\u0438\u0431\u0443\u0434\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"cs\">var advanced = RabbitHutch.CreateBus(\"host=localhost:5672;username=guest;password=guest\",    s =>       {         s.EnableConsoleLogger();         s.EnableSystemTextJson();         s.Register&lt;ITypeNameSerializer, SimpleTypeNameSerializer>();       }).Advanced; var exchange = advanced.ExchangeDeclare(\"SpecialExchangeName\", \"direct\"); var queue = advanced.QueueDeclare(\"SpecialQueueName\"); advanced.Bind(exchange, queue, routingKey: \"super-routing-key\"); advanced.Consume&lt;CardOrderSatisfiedEvent>(queue, (message, _) =>     Task.Factory.StartNew(() =>     {         var handler = app.Services.GetRequiredService&lt;ConsumerCardService>();         if(message.Body.ShouldBeNotified)             handler.PushUser(message.Body);     }));  \/\/ BAD CODE, \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0434\u0435\u043c\u043e class SimpleTypeNameSerializer : ITypeNameSerializer {     public string Serialize(Type type) => type.Name;     public Type DeSerialize(string typeName) => typeof(CardOrderSatisfiedEvent); }   <\/code><\/pre>\n<p>\u041e\u0431\u044b\u0447\u043d\u043e \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 EasyNetQ \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e nuget-\u0441\u0431\u043e\u0440\u043a\u0443 \u0441 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u044c\u044e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f <code>messageType<\/code>. \u0412 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u043c \u0434\u0435\u043c\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 nuget<em>&#8212;<\/em>\u0441\u0431\u043e\u0440\u043a\u0438, \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043d\u0435\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f <code>Type.FullName<\/code> \u0434\u0432\u0443\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 <code>CardOrderSatisfiedEvent<\/code> \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043b\u0430\u0441\u0441\u0430 <code>SimpleTypeNameSerializer<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0441\u0431\u043e\u0440\u043a\u0443 \u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u043c \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u043e: \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c &#171;\u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435&#187; \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0438 \u043d\u0430\u0440\u0443\u0448\u0438\u0442\u044c \u043f\u0430\u043a\u0442.<\/p>\n<p>\u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432 \u0434\u043e\u043a\u0435\u0440\u0435 RabbitMq \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043e\u0431\u0449\u0430\u044e\u0442\u0441\u044f \u0441 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c:<\/p>\n<pre><code class=\"cs\">docker run --rm -d -p 15671:15671\/tcp -p 15672:15672\/tcp -p 25672:25672\/tcp  -p 4369:4369\/tcp -p 5671:5671\/tcp -p 5672:5672\/tcp rabbitmq:3-management<\/code><\/pre>\n<h3>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f  <\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f \u0441 \u043f\u043e\u043d\u044f\u0442\u0438\u044f\u043c\u0438 <em>consumer \/ provider<\/em> \u0438 <em>subscriber \/ publisher<\/em>, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0437\u0434\u0435\u0441\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u0430 \u0438 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0443\u0442\u0430\u0442\u044c<em>. <\/em>\u041a\u0430\u043a \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438,<em> <\/em>\u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u0445 Pact <em>consumer`\u043e\u043c<\/em> \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043a\u043b\u0438\u0435\u043d\u0442, \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c API. \u0422\u0430\u043a\u0436\u0435 \u043f\u043e\u0434 \u044d\u0442\u0438\u043c \u043f\u043e\u043d\u044f\u0442\u0438\u0435\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a, \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u043b\u0438 <em>subscriber<\/em> \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u0445 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u043d\u0430\u0434 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 <em>subscriber,<\/em> \u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <em>publisher. <\/em>\u0418\u0437 \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442, \u0447\u0442\u043e \u0432 \u043d\u0430\u0448\u0435\u0439 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438, \u0441\u0435\u0440\u0432\u0438\u0441 Demo.Provider \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (<em>publisher<\/em>) \u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f (<em>provider<\/em>), \u0430 \u0441\u0435\u0440\u0432\u0438\u0441 Demo.Consumer \u0441\u043b\u0443\u0436\u0438\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (<em>subscriber<\/em>) \u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f (<em>consumer<\/em>).<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 \u043f\u0430\u043f\u043a\u0435 <em>Consumer.ContractTests\/RabbitMq<\/em> \u043a\u043b\u0430\u0441c CardOrderSatisfiedEventTests \u0438 \u043d\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 CardOrderSatisfiedEventTests<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">public class CardOrderSatisfiedEventTests {     private readonly IMessagePactBuilderV4 _pactBuilder;     private const string ComType = \"RABBITMQ\";      public CardOrderSatisfiedEventTests(ITestOutputHelper testOutputHelper)     {         var pact = Pact.V4(consumer: \"Demo.Consumer\", provider: \"Demo.Provider\", new PactConfig         {             Outputters = new[] {new PactXUnitOutput(testOutputHelper)},             DefaultJsonSettings = new JsonSerializerOptions             {                 PropertyNameCaseInsensitive = true,                 PropertyNamingPolicy = JsonNamingPolicy.CamelCase             }         });         _pactBuilder = pact.WithMessageInteractions();     }      [Fact(DisplayName = \"Demo.Provider \u043f\u0440\u0438\u0441\u044b\u043b\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0438 \u043f\u0443\u0448 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \" +                         \"\u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\")]     public void CardOrderSatisfiedEvent_WhenModelCorrectAndShouldBePushed_SendsPush()     {         \/\/ Arrange         var message = new         {             UserId = Match.Type(\"rabbitmqUserId\"),             CardCode = Match.Integer(100),             ShouldBeNotified = true         };          _pactBuilder             .ExpectsToReceive($\"{ComType}: CardOrderSatisfiedEvent with push\")             .WithMetadata(\"exchangeName\", \"SpecialExchangeName\")             .WithMetadata(\"routingKey\", \"super-routing-key\")             .WithJsonContent(message)              \/\/ Act             .Verify&lt;CardOrderSatisfiedEvent>(msg =>             {                 \/\/ Assert                 \/\/ \u043c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 IConsumer.Handle \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430                 \/\/_consumerCardService.Verify(x => x.PushUser(msg), Times.Once);             });     }          [Fact(DisplayName = \"Demo.Provider \u043f\u0440\u0438\u0441\u044b\u043b\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0438 \u043f\u0443\u0448 \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \" +                         \"\u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\")]     public void CardOrderSatisfiedEvent_WhenModelCorrectAndShouldNotBePushed_DontSendPush()     {         \/\/ Arrange         var message = new         {             UserId = Match.Type(string.Empty),             CardCode = Match.Integer(100),             ShouldBeNotified = false         };          _pactBuilder             .ExpectsToReceive($\"{ComType}: CardOrderSatisfiedEvent no push\")             .WithMetadata(\"exchangeName\", \"SpecialExchangeName\")             .WithMetadata(\"routingKey\", \"super-routing-key\")             .WithJsonContent(message)              \/\/ Act             .Verify&lt;CardOrderSatisfiedEvent>(msg =>             {                 \/\/ Assert                 \/\/ \u043c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 IConsumer.Handle \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430                 \/\/_consumerCardService.Verify(x => x.PushUser(msg), Times.Never);             });     } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e <code>IPactBuilderV4<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>IMessagePactBuilderV4<\/code>, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u0430\u043a\u0442\u044b \u0434\u043b\u044f \u0441\u0438\u0441\u0442\u0435\u043c, \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0421\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0443\u0442\u0435\u043c \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 <code>WithMessageInteractions()<\/code>. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u0434 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0447\u0430\u0441\u0442\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u0434\u043b\u044f HTTP;<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>ExpectsToReceive()<\/code> \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 <code>UponReceiving()<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u0430, \u0430 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <code>WithJsonContent()<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 <code>WithMetadata()<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432\u0440\u043e\u0434\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432, \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u0438 \u043f\u0440\u043e\u0447\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0442\u0435\u0441\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043e\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u0430 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c SpecialExchangeName \u0438 \u0442\u043e\u043f\u0438\u043a\u0430 super-routing-key;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 <code>Verify<\/code> \u0432\u0441\u0435 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 pact.json, \u043d\u043e, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 HTTP \u0432\u0435\u0440\u0441\u0438\u0438, \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440, \u0430 \u0432 \u0441\u0435\u043a\u0446\u0438\u0438 <em>Assert<\/em> \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c, \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f <em>event-driven<\/em> \u0441\u0438\u0441\u0442\u0435\u043c, Pact \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043e\u0442 \u043f\u043e\u043d\u044f\u0442\u0438\u044f \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u043d\u0435 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0443\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044e \u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u043e\u0442\u0447\u0430\u0441\u0442\u0438 \u0435\u0451 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438. \u0412\u0432\u0438\u0434\u0443 \u0442\u0430\u043a\u043e\u0433\u043e \u043e\u0431\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432, Pact \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u0430\u0436\u0434\u044b\u043c \u0438\u0437 \u043d\u0438\u0445 \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0442\u043e\u0434 <code>WithMetadata()<\/code>. <\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0432\u0440\u043e\u0434\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0439 \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u043e\u0432 \u0438 \u0442\u043e\u043f\u0438\u043a\u043e\u0432 \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043c, \u0433\u0434\u0435 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0438\u0445 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0443 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0435\u0442\u0441\u044f. \u0414\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u0442\u0435\u0441\u0442\u0435 (\u043a\u0430\u043a \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435) \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0447\u0438\u0441\u0442\u043e \u0437\u0430\u0431\u044b\u0442\u043e, \u0447\u0442\u0435\u043d\u0438\u0435 \u0438\u0437 IConfiguration \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0438\u043b\u0438\u0439, \u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043e\u0442 \u0441\u0440\u0435\u0434\u044b \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f (<em>dev, test, prod<\/em>) \u043b\u0438\u0448\u044c \u0443\u0441\u0443\u0433\u0443\u0431\u043b\u044f\u0435\u0442 \u0432\u0441\u044e \u044d\u0442\u0443 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u043e\u0432\u0435\u0440\u0438\u0435 \u043a \u0442\u0435\u0441\u0442\u0443, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0435\u043c\u0443 \u0434\u0430\u043d\u043d\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b, \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e.<\/p>\n<h3>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 \u043f\u0430\u043f\u043a\u0435 <em>Provider.ContractTests\/RabbitMq<\/em> \u043a\u043b\u0430\u0441c ContractWithConsumerTests \u0438 \u043d\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 ContractWithConsumerTests <\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">public class ContractWithConsumerTests : IDisposable {     private readonly PactVerifier _pactVerifier;     private const string ComType = \"RABBITMQ\";      private readonly JsonSerializerOptions _jsonSerializerOptions = new()     {         PropertyNameCaseInsensitive = true,         PropertyNamingPolicy = JsonNamingPolicy.CamelCase     };      public ContractWithConsumerTests(ITestOutputHelper testOutputHelper)      {         _pactVerifier = new PactVerifier(\"Demo.Provider\", new PactVerifierConfig         {             Outputters = new []{ new PactXUnitOutput(testOutputHelper) }         });     }          [Fact(DisplayName = \"RabbitMq \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b \u0441 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0435\u043c Demo.Consumer \u0441\u043e\u0431\u043b\u044e\u0434\u0430\u044e\u0442\u0441\u044f\")]     public void Verify_RabbitMqDemoConsumerContacts()     {         \/\/ Arrange         var userId = \"rabbitUserId\";         var cardCode = 100;         var metadata = new Dictionary&lt;string, string>         {             {\"exchangeName\", \"SpecialExchangeName\"},             {\"routingKey\", \"super-routing-key\"}         };         _pactVerifier.WithMessages(scenarios =>             {                 scenarios.Add($\"{ComType}: CardOrderSatisfiedEvent with push\", builder =>                 {                     builder.WithMetadata(metadata).WithContent(() => new CardOrderSatisfiedEvent                     {                         UserId = userId, CardCode = cardCode, ShouldBeNotified = true                     });                 });                 scenarios.Add($\"{ComType}: CardOrderSatisfiedEvent no push\", builder =>                 {                     builder.WithMetadata(metadata).WithContent(() => new CardOrderSatisfiedEvent                     {                         UserId = userId, CardCode = cardCode, ShouldBeNotified = false                     });                 });             }, _jsonSerializerOptions)             .WithFileSource(new FileInfo(@\"..\\..\\..\\pacts\\Demo.Consumer-Demo.Provider.json\"))                          \/\/ Act &amp;&amp; Assert             .WithFilter(ComType)             .Verify();     }      public void Dispose()     {         _pactVerifier?.Dispose();     } }           <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0440\u0430\u043d\u044c\u0448\u0435 <code>WithHttpEndpoint()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u043e\u0435 \u043d\u0430\u043c\u0438 \u0440\u044f\u0434\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043c\u0435\u0442\u043e\u0434 <code>WithMessages()<\/code> \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439 \u043f\u043e\u0440\u0442 \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u0435 \u043c\u043e\u043a-\u0445\u043e\u0441\u0442\u0430 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443<a href=\"http:\/\/localhost:49152\/pact-messages\/\" rel=\"noopener noreferrer nofollow\"> <u>http:\/\/localhost:port\/pact-messages\/<\/u><\/a>. \u0422\u0430\u043a\u0436\u0435 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430\u0431\u043e\u0440 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432, \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0442\u0435\u043b\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f. \u0422\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043e\u0431\u0443\u0441\u043b\u043e\u0432\u043b\u0435\u043d\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435\u043c \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 Pact. \u041c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044e \u0432 \u0432\u0438\u0434\u0435 MessageProvider \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u043d\u0430\u0448\u0438\u043c\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c\u0438. \u041f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0442\u0435\u0441\u0442\u0430 \u044d\u0442\u043e\u0442 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0431\u0440\u043e\u043a\u0435\u0440 \u0441\u0432\u0435\u0440\u0438\u0442 \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0435\u0441\u044f \u0432 \u043d\u0451\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u0432\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 pact.json \u0438 \u0432\u044b\u0434\u0430\u0441\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 <code>Verify()<\/code>. \u0422\u0430\u043a\u0436\u0435, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0442\u0435\u043f\u0435\u0440\u044c \u0432 \u0444\u0430\u0439\u043b\u0435 \u0441 \u043f\u0430\u043a\u0442\u0430\u043c\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u043a\u0430\u043a \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435, \u0442\u0430\u043a \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 <code>WithFilter()<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435.<\/p>\n<h3>\u0421\u043c\u043e\u0442\u0440\u0438\u043c pact.json \u0438 \u0441\u043d\u043e\u0432\u0430 \u043b\u043e\u043c\u0430\u0435\u043c API<\/h3>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u0440\u043e\u0433\u043e\u043d\u0430 \u0442\u0435\u0441\u0442\u0430 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 Demo.Provider \u0432 \u0443\u0436\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u043d\u0430\u043c \u0444\u0430\u0439\u043b \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0435\u0449\u0435 \u0434\u0432\u0430 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432 \u043e\u0431\u0449\u0435\u043c \u043f\u043e\u0445\u043e\u0436\u0430 \u043d\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b. \u041a \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u043e\u0442\u043b\u0438\u0447\u0438\u044f\u043c \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043d\u0435\u0441\u0442\u0438 \u0440\u0430\u0437\u0432\u0435 \u0447\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c\u043e\u0435 \u0443\u0436\u0435 \u043d\u0430\u043c\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0441\u0435\u043a\u0446\u0438\u0438 <code>metadata<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0438\u043d\u043e\u0439 \u0442\u0438\u043f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432 \u0441\u0435\u043a\u0446\u0438\u0438 <code>type<\/code>.<\/p>\n<pre><code class=\"json\">{   \"contents\": {     \"content\": {       \"cardCode\": 100,       \"shouldBeNotified\": true,       \"userId\": \"rabbitmqUserId\"     },     \"contentType\": \"application\/json\",     \"encoded\": false   },   \"description\": \"RABBITMQ: CardOrderSatisfiedEvent with push\",   \"matchingRules\": {     \"body\": {       \"$.cardCode\": {         \"combine\": \"AND\",         \"matchers\": [{\"match\": \"integer\"}]       },       \"$.userId\": {         \"combine\": \"AND\",         \"matchers\": [{\"match\": \"type\"}]       }    } },   \"metadata\": {     \"exchangeName\": \"SpecialExchangeName\",     \"routingKey\": \"super-routing-key\" },     \"pending\": false,     \"type\": \"Asynchronous\/Messages\" },  {\"description\": \"RABBITMQ: CardOrderSatisfiedEvent no push\"...} <\/code><\/pre>\n<p>\u041e\u0441\u043e\u0431\u044b\u0445 \u043e\u0442\u043b\u0438\u0447\u0438\u0439 \u0432 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u043e\u0442 HTTP \u0442\u0435\u0441\u0442\u0430 \u043d\u0435\u0442 \u0438 \u043f\u0440\u0438 \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u0438 \u043d\u0435\u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442. \u0422\u0430\u043a, \u043f\u0440\u0438 \u043a\u0430\u043a\u043e\u043c-\u043b\u0438\u0431\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u043b\u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 Pact \u0432\u044b\u0434\u0430\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u0432\u0440\u043e\u0434\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439:<\/p>\n<pre><code class=\"powershell\">Failures:  1) Verifying a pact between Demo.Consumer and Demo.Provider - RABBITMQ: CardOrderSatisfiedEvent with push     1.1) has a matching body            $.userId -> Expected 'rabbitmqUserId' (String) to be equal to 'diffUserId' (String)            $ -> Actual map is missing the following keys: cardCode      1.2) has matching metadata            Expected message metadata 'routingKey' to have value '\"super-routing-key\"' but was '\"diff-super-routing-key\"'            Expected message metadata 'exchangeName' to have value '\"SpecialExchangeName\"' but was '\"DiffSpecialExchangeName\"' <\/code><\/pre>\n<h2>\u0417\u043d\u0430\u043a\u043e\u043c\u0438\u043c\u0441\u044f \u0441 PactBroker<\/h2>\n<p>\u0418\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u0432\u044b\u0448\u0435<s>\u0441\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e<\/s> \u0441\u0434\u0435\u043b\u0430\u043d\u043d\u043e\u0433\u043e \u0438 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u043a \u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u043c\u0438 \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445, \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u043a\u0430\u043a \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u043e HTTP, \u0442\u0430\u043a \u0438 \u043f\u043e\u043b\u0430\u0433\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043d\u0430 RabbitMq. \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u043c\u044b \u0432\u0441\u0435 \u0435\u0449\u0435 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0444\u0430\u0439\u043b Demo.Consumer-Demo.Provider.json \u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442, \u0447\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e.<\/p>\n<p>\u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0440\u043e\u043b\u044c \u0434\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430 \u043f\u0430\u043a\u0442\u043e\u0432 \u043d\u0430 \u0441\u0435\u0431\u044f \u043c\u043e\u0436\u0435\u0442 \u0432\u0437\u044f\u0442\u044c \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 &#8212; PactBroker. \u041a\u0430\u043a \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0446\u0435\u043b\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u044d\u0442\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0430 \u0444\u0430\u0439\u043b\u0430 pact.json, \u043e\u0434\u043d\u0430\u043a\u043e, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043e\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u043f\u0430\u043d\u0435\u043b\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0430\u043a\u0442\u043e\u0432.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b PactBroker`\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432. \u0412 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439<a href=\"https:\/\/docs.pact.io\/pact_broker\/docker_images\" rel=\"noopener noreferrer nofollow\"> <u>\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/u><\/a><u> <\/u>\u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0432\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u0445 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 PactBroker, \u043c\u044b \u0436\u0435 \u043f\u043e\u0434\u043d\u0438\u043c\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e docker-compose, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043d\u0438\u0436\u0435. \u0424\u0430\u0439\u043b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u0421\u0423\u0411\u0414 PostgreSQL 15, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u0432\u0438\u0441\u044f\u0449\u0435\u0433\u043e \u043e\u0442 \u043d\u0435\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u0431\u0440\u043e\u043a\u0435\u0440\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 docker-compose.yaml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>version: \"3.9\"  services:   postgres:     image: postgres:15     container_name: pact-postgres     ports:       - \"5432:5432\"     healthcheck:       test: psql postgres -U postgres --command 'SELECT 1'     environment:       POSTGRES_USER: postgres       POSTGRES_PASSWORD: postgres       POSTGRES_DB: postgres      broker:     image: pactfoundation\/pact-broker:latest-multi     container_name: pact-broker-1     depends_on:       - postgres     ports:       - \"9292:9292\"     restart: always     environment:       PACT_BROKER_ALLOW_PUBLIC_READ: \"false\"       PACT_BROKER_BASIC_AUTH_USERNAME: admin       PACT_BROKER_BASIC_AUTH_PASSWORD: pass       PACT_BROKER_DATABASE_URL: \"postgres:\/\/postgres:postgres@postgres\/postgres\"      healthcheck:       test: [\"CMD\", \"curl\", \"--silent\", \"--show-error\", \"--fail\",              \"http:\/\/pactbroker:pactbroker@localhost:9292\/diagnostic\/status\/heartbeat\"]       interval: 1s       timeout: 2s       retries: 5 <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0431\u0440\u043e\u043a\u0435\u0440\u0430.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/46f\/0c8\/4b8\/46f0c84b8689060fa864c96c6f07661e.png\" alt=\"\u0417\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 Postgress \u0438 PactBroker\" title=\"\u0417\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 Postgress \u0438 PactBroker\" width=\"1154\" height=\"190\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/46f\/0c8\/4b8\/46f0c84b8689060fa864c96c6f07661e.png\"\/><\/p>\n<div><figcaption>\u0417\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 Postgress \u0438 PactBroker<\/figcaption><\/div>\n<\/figure>\n<h3>\u041f\u0440\u0438\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u0435\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0430 \u043f\u0430\u043a\u0442\u043e\u0432<\/h3>\n<h4>\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0430\u043a\u0442\u043e\u0432 \u0432 PactBroker<\/h4>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 PactNet \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438\u0437 \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u043f\u0430\u043a\u0442\u044b (\u0447\u0442\u043e \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u043e\u0432\u0441\u0435\u043c \u0441\u043a\u043e\u0440\u043e), \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0445 \u0432 \u043d\u0435\u0433\u043e \u043e\u043d\u0430<a href=\"https:\/\/github.com\/pact-foundation\/pact-net\/issues\/474\" rel=\"noopener noreferrer nofollow\"> <u>\u0443\u0442\u0440\u0430\u0442\u0438\u043b\u0430<\/u><\/a>. \u0421\u0443\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u043e, \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u0432 \u0441\u0440\u0435\u0434\u0435 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0448\u0430\u0433 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0430\u043a\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f pact-cli. \u041d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u0431\u0437\u043e\u0440 pact-cli \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u0440\u0430\u043c\u043a\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430, \u0432 \u043d\u0430\u0448\u0435\u043c \u0434\u0435\u043c\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0440\u0435\u0447\u0438\u0432\u043e\u0435, \u043e\u0434\u043d\u0430\u043a\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0434\u043b\u044f \u0446\u0435\u043b\u0435\u0439 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 \u043f\u0430\u043f\u043a\u0435 <em>shared<\/em> \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0440\u043e\u043a\u0435\u0440\u0443 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u0441\u0435\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u0430. \u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0446\u0435\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>IClassFixture<\/code> \u0438 \u043c\u0435\u0442\u043e\u0434 <code>Dispose()<\/code>. PactBroker \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u0447\u0435\u043d\u044c \u043c\u0435\u0442\u043e\u0434\u043e\u0432 API \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c, \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u0441\u044f \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0432 \u043f\u0430\u043d\u0435\u043b\u0438 \u0431\u0440\u043e\u043a\u0435\u0440\u0430. \u0414\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0430\u043a\u0442\u043e\u0432 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 pacts\/provider\/{provider}\/consumer\/{consumer}\/version\/{consumerVersion}.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0430\u043a\u0442\u043e\u0432 \u0438 \u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e <code>PactBrokerPublisher<\/code>. \u0412 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0435\u043c\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043c\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u043e\u0439, \u0441\u0443\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u0430 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u0432\u044b\u0437\u043e\u0432\u0443 PUT \u043c\u0435\u0442\u043e\u0434\u0430 \u043f\u043e \u043f\u0443\u0442\u0438, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u043c\u0443 \u0432\u044b\u0448\u0435:<\/p>\n<pre><code class=\"cs\">private readonly HttpClient _httpClient;      public PactBrokerPublisher(HttpClient httpClient) {_httpClient = httpClient;}      public async Task Publish(string consumer, string provider, string content, string consumerVersion) {     var response = await _httpClient     .PutAsync($\"pacts\/provider\/{provider}\/consumer\/{consumer}\/version\/{consumerVersion}\",     new StringContent(content)     {       Headers = { ContentType = new MediaTypeHeaderValue(\"application\/json\") }     });      if (response.IsSuccessStatusCode == false)         throw new ArgumentNullException($\"\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0430\u043a\u0442\u0430 \u0432 PactBroker: {response.StatusCode}\"); } <\/code><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043f\u0430\u043a\u0442\u043e\u0432 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0432\u0441\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441 <code>PactBrokerFixture<\/code> \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0432 \u043d\u0451\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>IDisposable<\/code>. \u0426\u0435\u043b\u044c \u043a\u043b\u0430\u0441\u0441\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0444\u0430\u0439\u043b\u0430 \u043f\u0430\u043a\u0442\u043e\u0432 PactBroker`\u0443 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 <code>Dispose()<\/code>.<\/p>\n<pre><code class=\"cs\">private readonly Uri _pactBrokerUri = new (\"http:\/\/localhost:9292\"); private readonly string _pactUsername = \"admin\"; private readonly string _pactPassword = \"pass\"; private readonly PactBrokerPublisher _pactBrokerPublisher;  public string ConsumerVersion { get; set; }  public IPact? PactInfo { get; set; }      public PactBrokerFixture() {     var baseAuthenticationString = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes($\"{_pactUsername}:{_pactPassword}\"));     _pactBrokerPublisher = new PactBrokerPublisher(new HttpClient     {         DefaultRequestHeaders =         {             Authorization = new AuthenticationHeaderValue(\"Basic\", baseAuthenticationString)         },         BaseAddress = _pactBrokerUri     }); }      public void Dispose() {     Task.Run(async () =>     {         var versionSuffix = Guid.NewGuid().ToString().Substring(0, 5);         var pactJson = await File.ReadAllTextAsync($\"{PactInfo.Config.PactDir}\/{PactInfo.Consumer}-{PactInfo.Provider}.json\");         await _pactBrokerPublisher.Publish(                 consumer: PactInfo.Consumer, provider: PactInfo.Provider, content: pactJson,                 $\"{ConsumerVersion}-{versionSuffix}\");     }); } <\/code><\/pre>\n<p>\u0414\u0435\u043b\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0437\u0430 \u043c\u0430\u043b\u044b\u043c, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<ol>\n<li>\n<p>\u041a\u043b\u0430\u0441\u0441\u044b OrderCardTests \u0438 CardOrderSatisfiedEventTests \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 IClassFixture&lt;PactBrokerFixture>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u043d\u0435\u0434\u0440\u044f\u044e\u0442 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c PactBrokerFixture.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0431\u043e\u0440\u043a\u0430 Consumer.Domain \u0438\u043c\u0435\u0435\u0442 \u0442\u0435\u0433 \u0432\u0435\u0440\u0441\u0438\u0438 &lt;Version>1.0.0&lt;\/Version>.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u043a\u043b\u0430\u0441\u0441\u043e\u0432 OrderCardTests \u0438 CardOrderSatisfiedEventTests \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0444\u0438\u043a\u0441\u0442\u0443\u0440\u044b: ConsumerVersion \u0438 PactInfo.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"cs\">brokerFixture.PactInfo = pact; brokerFixture.ConsumerVersion = Assembly     .GetAssembly(typeof(CardOrderSatisfiedEvent))?     .GetCustomAttribute&lt;AssemblyInformationalVersionAttribute>()?     .InformationalVersion;<\/code><\/pre>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u043c\u0438\u043d\u0443\u0441\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043a \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u043f\u0430\u043a\u0442\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0430\u043c \u043a\u043b\u0430\u0441\u0441 <code>PactBrokerFixture<\/code>. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u0442\u0430\u043a\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0435\u0433\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432 \u043d\u0430\u0448\u0435\u043c \u0434\u0435\u043c\u043e \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043a\u043e\u0434\u0430, \u0442\u0430\u043a\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043a\u0430\u043a \u0430\u0434\u0440\u0435\u0441 \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u0438 \u0443\u0447\u0435\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <code>PactBrokerFixture<\/code>. \u041e\u0434\u043d\u0430\u043a\u043e \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u0433\u0434\u0435 \u044d\u0442\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438, \u0442\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435 \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442, \u0447\u0442\u043e \u0432\u043d\u043e\u0432\u044c \u043e\u0442\u0441\u044b\u043b\u0430\u0435\u0442 \u043d\u0430\u0441 \u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0448\u0430\u0433\u0430\u043c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0434\u0435\u043f\u043b\u043e\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u0443\u0447\u0435\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0432 IConfiguration \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0442\u0435\u0441\u0442\u043e\u0432, \u0438 \u0442\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0436\u0438\u0442\u044c\u0441\u044f.<\/p>\n<h4>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u0430\u043a\u0442\u043e\u0432 \u0438\u0437 PactBroker<\/h4>\n<p>\u0414\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0430\u043a\u0442\u043e\u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 PactNet \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <code>WithPactBrokerSource()<\/code>, \u0432\u044b\u0437\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u0434\u0432\u0430 \u043d\u0430\u0448\u0438\u0445 \u0442\u0435\u0441\u0442\u0430 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430.<\/p>\n<pre><code class=\"cs\">_pactVerifier     ...     .WithPactBrokerSource(new Uri(\"http:\/\/localhost:9292\"), options =>     {         options.BasicAuthentication(\"admin\", \"pass\");         options.PublishResults(_providerVersion + $\" {Guid.NewGuid().ToString().Substring(0, 5)}\");     })     \/\/ .WithFileSource(new FileInfo(@\"..\\..\\..\\pacts\\Demo.Consumer-Demo.Provider.json\"))     ... <\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>BasicAuthentication()<\/code> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0432 PactBroker, \u0443\u0447\u0435\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u044b\u043b\u0438 \u0437\u0430\u0434\u0430\u043d\u044b \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432. \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043c\u0435\u0442\u043e\u0434 <code>PublishResult()<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043b\u0438\u0448\u044c \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u043e\u043c \u0432 \u043f\u0430\u043d\u0435\u043b\u0438 PactBroker. \u041f\u043e\u043b\u0435 <code>_providerVersion<\/code> \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e ConsumerVersion, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0432\u0438\u0434\u0435\u043b\u0438 \u0440\u0430\u043d\u0435\u0435, \u043d\u043e \u0442\u0435\u0433 \u0432\u0435\u0440\u0441\u0438\u0438 \u0443\u0436\u0435 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u0441\u0431\u043e\u0440\u043a\u0435 Provider.Contracts.<\/p>\n<h3>\u041e\u0431\u0437\u043e\u0440 \u043f\u0430\u043d\u0435\u043b\u0438 PactBroker<\/h3>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446 \u043e\u0431\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u043e\u043a\u0440\u044b\u0442\u044b \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u043c\u0438 \u0442\u0435\u0441\u0442\u0430\u043c\u0438, \u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0430\u043a\u0442\u044b \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e PactBroker. \u041f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0442\u0435\u0441\u0442\u044b \u0432 \u043f\u0430\u043f\u043a\u0435 <em>consumer<\/em> \u0438 <em>provider<\/em>. \u0415\u0441\u043b\u0438 \u0432\u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u043e\u0448\u043b\u0438, \u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0432 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443<a href=\"http:\/\/localhost:9292\/\" rel=\"noopener noreferrer nofollow\"> <u>http:\/\/localhost:9292\/<\/u><\/a>, \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0443, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0449\u0443\u044e \u0438\u043c\u0435\u044e\u0449\u0438\u0435\u0441\u044f \u0443 PactBroker \u043f\u0430\u043a\u0442\u044b.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c19\/0a7\/1e7\/c190a71e7bc6d51d11634c328bc03abb.png\" alt=\"\u0414\u043e\u043c\u0430\u0448\u043d\u0430\u044f\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0430\u043d\u0435\u043b\u0438 \u0431\u0440\u043e\u043a\u0435\u0440\u0430\" title=\"\u0414\u043e\u043c\u0430\u0448\u043d\u0430\u044f\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0430\u043d\u0435\u043b\u0438 \u0431\u0440\u043e\u043a\u0435\u0440\u0430\" width=\"1428\" height=\"423\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c19\/0a7\/1e7\/c190a71e7bc6d51d11634c328bc03abb.png\"\/><\/p>\n<div><figcaption>\u0414\u043e\u043c\u0430\u0448\u043d\u0430\u044f\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0430\u043d\u0435\u043b\u0438 \u0431\u0440\u043e\u043a\u0435\u0440\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 \u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f: \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430, \u0434\u0430\u0442\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f, \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0432\u0435\u0431 \u0445\u0443\u043a\u0430 (\u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435) \u0438 \u0434\u0430\u0442\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430. \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441\u0442\u043e\u043b\u0431\u0435\u0446, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430, \u043e\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0446\u0432\u0435\u0442\u0430: \u043a\u0440\u0430\u0441\u043d\u044b\u0439 &#8212; \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0435 \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u0430, \u0436\u0435\u043b\u0442\u044b\u0439 &#8212; \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0435\u0449\u0435 \u043d\u0435 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043b\u0430\u0441\u044c \u0438 \u0437\u0435\u043b\u0435\u043d\u044b\u0439 &#8212; \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0432\u0435\u0440\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430. <\/p>\n<p>\u0411\u0440\u043e\u043a\u0435\u0440 \u0445\u0440\u0430\u043d\u0438\u0442 \u043f\u0430\u043a\u0442\u044b \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2aa\/ba5\/893\/2aaba58939da7d0f1dd99a98a22f1662.png\" alt=\"\u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043f\u0430\u043a\u0442\u043e\u0432\" title=\"\u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043f\u0430\u043a\u0442\u043e\u0432\" width=\"1254\" height=\"624\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2aa\/ba5\/893\/2aaba58939da7d0f1dd99a98a22f1662.png\"\/><\/p>\n<div><figcaption>\u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043f\u0430\u043a\u0442\u043e\u0432<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u0438\u043a\u043e\u043d\u043a\u0443 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u043f\u0430\u043a\u0442\u043e\u0432. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 PactV4 \u0444\u0430\u0439\u043b \u043f\u0430\u043a\u0442\u0430 \u043f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u043d\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0444\u043e\u0440\u043c\u0430\u0442 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u0430\u043a JSON \u0444\u0430\u0439\u043b. \u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0432\u0435\u0440\u0441\u0438\u0438, \u0432\u0440\u043e\u0434\u0435 PactV3 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u0430\u0440\u0441\u044f\u0442\u0441\u044f. \u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/161\/842\/810\/161842810b4438bbb7c8e1f4a9ab07c6.png\" alt=\"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0430\u043a\u0442\u0430 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 PactV4\" title=\"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0430\u043a\u0442\u0430 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 PactV4\" width=\"1600\" height=\"407\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/161\/842\/810\/161842810b4438bbb7c8e1f4a9ab07c6.png\"\/><\/p>\n<div><figcaption>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0430\u043a\u0442\u0430 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 PactV4<\/figcaption><\/div>\n<\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5e1\/aa4\/8d2\/5e1aa48d228b3e2888dae1374e44c52b.png\" alt=\"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0430\u043a\u0442\u0430 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 PactV3\" title=\"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0430\u043a\u0442\u0430 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 PactV3\" width=\"1600\" height=\"466\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5e1\/aa4\/8d2\/5e1aa48d228b3e2888dae1374e44c52b.png\"\/><\/p>\n<div><figcaption>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0430\u043a\u0442\u0430 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 PactV3<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u0432\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0443\u0434\u043e\u0431\u043d\u0435\u0435, \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441 PactV4 \u0432\u0441\u0435 \u0435\u0449\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0432\u0435\u043d. \u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0435\u0439, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 PactNet, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0430\u043a\u0442\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c\u0441\u044f \u043a\u0440\u0430\u0441\u0438\u0432\u0435\u0435.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u0432 \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438. \u0412 \u043d\u0435\u0439 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439. \u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u043c\u0435\u0436\u0434\u0443 Demo.Consumer \u0432\u0435\u0440\u0441\u0438\u0438 <code>1.0.0-d1549<\/code> \u0438 Demo.Provider \u0432\u0435\u0440\u0441\u0438\u0438 <code>1.0.0<\/code> \u0441\u043e\u0431\u043b\u044e\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0435\u0438\u043c\u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u0430\u043c\u0438. \u041d\u043e, \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0432\u0434\u0440\u0443\u0433 \u0432\u043d\u0435\u0441\u0435\u0442 \u0432 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u043d\u0435\u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435, \u0442\u043e \u043f\u0430\u043a\u0442 \u043c\u0435\u0436\u0434\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0440\u0443\u0448\u0435\u043d. \u0422\u0430\u043a, Demo.Provider \u0432\u0435\u0440\u0441\u0438\u0438 <code>2.0.0<\/code> \u0438 Demo.Consumer \u0432\u0435\u0440\u0441\u0438\u0438 <code>1.0.0-d1549<\/code> \u0443\u0436\u0435 \u043d\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b24\/e6b\/38d\/b24e6b38de097e984d5abffb54acc903.png\" alt=\"\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438\" title=\"\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438\" width=\"1262\" height=\"575\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b24\/e6b\/38d\/b24e6b38de097e984d5abffb54acc903.png\"\/><\/p>\n<div><figcaption>\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u0441\u0442\u043e\u043b\u0431\u0446\u0435 Pact verified \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u043b\u0430\u0441\u044c \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d8a\/2b1\/809\/d8a2b180995ac1031700bf304a9481d5.png\" alt=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044f \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430\" title=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044f \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430\" width=\"933\" height=\"635\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d8a\/2b1\/809\/d8a2b180995ac1031700bf304a9481d5.png\"\/><\/p>\n<div><figcaption>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u044f \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u043e\u0431\u0437\u043e\u0440\u0430 \u043f\u0430\u043d\u0435\u043b\u0438 \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u043c\u0441\u044f \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043b\u044e\u0431\u043e\u0433\u043e \u0438\u0437 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432, \u043d\u0430\u0436\u0430\u0442\u0438\u0435\u043c \u043d\u0430 \u0435\u0433\u043e \u0438\u043c\u044f \u0438\u0437 \u0434\u043e\u043c\u0430\u0448\u043d\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u0418\u0437 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0433\u043e \u0437\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0433\u0440\u0430\u0444 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/297\/cc8\/fa8\/297cc8fa810045b3365bc968ad39c12b.png\" alt=\"\u0414\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432\" title=\"\u0414\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432\" width=\"970\" height=\"751\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/297\/cc8\/fa8\/297cc8fa810045b3365bc968ad39c12b.png\"\/><\/p>\n<div><figcaption>\u0414\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432<\/figcaption><\/div>\n<\/figure>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041d\u0430 \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u044d\u0442\u043e \u0432\u0441\u0451, \u0447\u0435\u043c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u0441\u044f \u0432 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 PactNet. \u041d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0434\u0430\u043d\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043e\u0431\u044a\u0435\u043c \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u0437\u0430 \u0434\u0432\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043d\u0435\u043c\u0430\u043b\u044b\u043c, \u044d\u0442\u043e \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Pact. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u043c\u0438 \u0442\u0430\u043a\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u043a\u0430\u043a:<\/p>\n<ul>\n<li>\n<p>ProviderState &#8212; \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0443 \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u0441\u0442\u043e\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0437\u0430\u043a\u0430\u0437\u0430 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a \u0443\u0436\u0435 \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u043a\u0430\u0437\u0430. \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u044a\u0435\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0442\u0435\u0441\u0442\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u0437\u0430\u0434\u0430\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430.<a href=\"https:\/\/github.com\/pact-foundation\/pact-net\/blob\/master\/samples\/OrdersApi\/Provider.Tests\/ProviderStateMiddleware.cs\" rel=\"noopener noreferrer nofollow\"> <u>\u041f\u0440\u0438\u043c\u0435\u0440<\/u><\/a><u> <\/u>\u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 PactNet;<\/p>\n<\/li>\n<li>\n<p>Branches, tags &#8212; Pact \u0438\u043c\u0435\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u0434\u0430, \u043b\u0443\u0447\u0448\u0435\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043e\u0432\u043e\u043a\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u0441 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c pact-cli;<\/p>\n<\/li>\n<li>\n<p>pact-cli;<\/p>\n<\/li>\n<li>\n<p>GraphQL API;<\/p>\n<\/li>\n<li>\n<p>WebHooks;<\/p>\n<\/li>\n<li>\n<p>Matchers &#8212; \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e\u0434 .NET \u0432\u0441\u0435 \u0436\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u044b\u0440\u0430\u044f \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 PactJS;<\/p>\n<\/li>\n<li>\n<p>\u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b PactBroker API, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432 \u0442\u0435\u043e\u0440\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0433\u0438\u0431\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432\u043e\u043e\u0431\u0449\u0435 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f PactNet;<\/p>\n<\/li>\n<li>\n<p>\u041c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e \u0435\u0449\u0435 \u043a\u0430\u0441\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0447\u0442\u0435\u043d\u0438\u044f \u043f\u0430\u043a\u0442\u043e\u0432 \u0438 \u0442.\u0434.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0447\u0435\u043c-\u0442\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u043e\u0434\u043d\u0430\u043a\u043e \u0438\u043d\u043e\u0433\u0434\u0430, \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0442 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0442\u044c <em>breaking changes<\/em> \u043d\u0430 \u0440\u0430\u043d\u043d\u0435\u043c \u044d\u0442\u0430\u043f\u0435. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u043a\u0430\u043a \u0438 \u043b\u044e\u0431\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0433\u043e \u0440\u043e\u0434\u0430 \u0442\u0435\u0441\u0442\u044b \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441 \u0443\u043c\u043e\u043c.<\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Pact \u0434\u043b\u044f .NET \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438. \u041a \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0435\u0451 \u043c\u0438\u043d\u0443\u0441\u0430\u043c \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043d\u0435\u0441\u0442\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 in-memory TestServer, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 (\u043b\u0438\u0448\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438) \u0438 \u0448\u0438\u0440\u043e\u043a\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 dynamic, \u0447\u0442\u043e \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043e\u0431\u0443\u0441\u043b\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0432\u0441\u0435 \u0432\u044b\u0448\u0435\u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u043c\u0438\u043d\u0443\u0441\u044b, \u0434\u043e\u0441\u0442\u043e\u0438\u043d\u0441\u0442\u0432 \u0443 Pact \u0432\u0441\u0435 \u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435, \u0438 \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u0441\u0442\u0430\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0432 \u0447\u0451\u043c \u043e\u043d\u0438 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/823082\/\"> https:\/\/habr.com\/ru\/articles\/823082\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/articles\/823080\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u0442\u0435\u043c\u044b \u0431\u044b\u043b\u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u0442\u0435\u043e\u0440\u0438\u044f \u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043f\u043e HTTP. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u043d\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0439, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043c\u0441\u044f \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c PactBroker.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 RabbitMq \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430. \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0441\u043f\u0438\u0441\u043e\u043a \u043c\u043e\u0436\u0435\u0442 \u0441\u0438\u043b\u044c\u043d\u043e \u0432\u0430\u0440\u044c\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f:<\/p>\n<ul>\n<li>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u0444\u043e\u0440\u043c\u0430\u0442)<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u0442\u0438\u043f \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0440\u043e\u0434\u0435 routing key, topics, reply-to \u0438 \u0442.\u0434. <\/p>\n<\/li>\n<\/ul>\n<h4>\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b \u0434\u043b\u044f \u0434\u0435\u043c\u043e<\/h4>\n<ul>\n<li>\n<p>.NET, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Pact \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 .netstandart2.0, \u0434\u0435\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 .NET 6;<\/p>\n<\/li>\n<li>\n<p>PactNet 5.0.0-beta.2 \u0438 PactNet.Abstractions 5.0.0-beta.2 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432; \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0440\u0435\u043b\u0438\u0437\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u043b\u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0432\u0435\u0440\u0441\u0438\u0438 4.5.0<a href=\"https:\/\/github.com\/pact-foundation\/pact-net\/issues\/468\" rel=\"noopener noreferrer nofollow\"> <u>\u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 non-ASCII \u0441\u0438\u043c\u0432\u043e\u043b\u044b<\/u><\/a>. \u0422\u0430\u043a\u0436\u0435, \u0434\u043e 5.x.x \u0432\u0435\u0440\u0441\u0438\u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f Newthonsoft.Json \u0432\u043c\u0435\u0441\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e System.Text.Json;<\/p>\n<\/li>\n<li>\n<p>\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 EasyNetQ 7.8.0 \u0438 EasyNetQ.Serialization.SystemTextJson 7.8.0 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 RabbitMq;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u0435\u0440 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 RabbitMq \u0438 PactBroker.<\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u043d\u043e\u0441\u0438\u0442 \u043b\u0438\u0448\u044c \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440 \u0434\u043b\u044f \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u044b PactNet \u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043e\u0431\u0438\u0435\u043c \u043f\u043e \u0447\u0438\u0441\u0442\u043e\u043c\u0443 \u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u043a\u043e\u0434\u0443. \u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u0434\u0435\u043c\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432<a href=\"https:\/\/github.com\/niyazz\/PactContractTestingDemo\/tree\/main\" rel=\"noopener noreferrer nofollow\"> <u>\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/u><\/a>.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438<\/h3>\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c RabbitMq \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043e \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043a\u0430\u0440\u0442\u044b. \u0422\u0430\u043a, \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 (Demo.Provider) \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u0441 \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u043e\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0443. \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c (Demo.Consumer) \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044f <code>ShouldBeNotified<\/code>, \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u043d\u0430 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0441\u043e\u0433\u043b\u0430\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0431\u044b\u043b\u0438 \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438:<\/p>\n<ul>\n<li>\n<p>\u041c\u043e\u0434\u0435\u043b\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u043e\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <code>CardOrderSatisfiedEvent<\/code> \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442: \u043a\u043e\u0434 \u043a\u0430\u0440\u0442\u044b-\u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430, \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0440\u0438\u0437\u043d\u0430\u043a \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u0430 SpecialExchangeName, \u0442\u0438\u043f direct;<\/p>\n<\/li>\n<li>\n<p>Routing-key \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 super-routing-key.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u0441\u0431\u043e\u0440\u043a\u0438 Consumer.Host \u0438 Provider.Host \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"xml\"> &lt;PackageReference Include=\"EasyNetQ\" Version=\"7.8.0\" \/>  &lt;PackageReference Include=\"EasyNetQ.Serialization.SystemTextJson\" Version=\"7.8.0\" \/><\/code><\/pre>\n<p>\u0421 \u0446\u0435\u043b\u044c\u044e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 Demo.Provider:  <\/p>\n<pre><code class=\"cs\">[HttpPost(\"order-satisfied\/{userId}\")] public async Task&lt;ActionResult> SendCardOrderSatisfiedEvent(string userId) {     var advancedBus = RabbitHutch.CreateBus(\"host=localhost\", s =>     {         s.EnableConsoleLogger();         s.EnableSystemTextJson();     }).Advanced;     var exchange = await advancedBus                         .ExchangeDeclareAsync(\"SpecialExchangeName\", \"direct\");     var message = new Message&lt;CardOrderSatisfiedEvent>(           new CardOrderSatisfiedEvent           {             UserId = userId,             CardCode = Random.Shared.Next(100)           });     await advancedBus.PublishAsync(exchange, \"super-routing-key\", false, message);     return Ok(); } <\/code><\/pre>\n<p>\u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 Program, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0433\u0434\u0435-\u043d\u0438\u0431\u0443\u0434\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"cs\">var advanced = RabbitHutch.CreateBus(\"host=localhost:5672;username=guest;password=guest\",    s =>       {         s.EnableConsoleLogger();         s.EnableSystemTextJson();         s.Register&lt;ITypeNameSerializer, SimpleTypeNameSerializer>();       }).Advanced; var exchange = advanced.ExchangeDeclare(\"SpecialExchangeName\", \"direct\"); var queue = advanced.QueueDeclare(\"SpecialQueueName\"); advanced.Bind(exchange, queue, routingKey: \"super-routing-key\"); advanced.Consume&lt;CardOrderSatisfiedEvent>(queue, (message, _) =>     Task.Factory.StartNew(() =>     {         var handler = app.Services.GetRequiredService&lt;ConsumerCardService>();         if(message.Body.ShouldBeNotified)             handler.PushUser(message.Body);     }));  \/\/ BAD CODE, \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0434\u0435\u043c\u043e class SimpleTypeNameSerializer : ITypeNameSerializer {     public string Serialize(Type type) => type.Name;     public Type DeSerialize(string typeName) => typeof(CardOrderSatisfiedEvent); }   <\/code><\/pre>\n<p>\u041e\u0431\u044b\u0447\u043d\u043e \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 EasyNetQ \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e nuget-\u0441\u0431\u043e\u0440\u043a\u0443 \u0441 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u044c\u044e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f <code>messageType<\/code>. \u0412 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u043c \u0434\u0435\u043c\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 nuget<em>&#8212;<\/em>\u0441\u0431\u043e\u0440\u043a\u0438, \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043d\u0435\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f <code>Type.FullName<\/code> \u0434\u0432\u0443\u0445 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 <code>CardOrderSatisfiedEvent<\/code> \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043b\u0430\u0441\u0441\u0430 <code>SimpleTypeNameSerializer<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0441\u0431\u043e\u0440\u043a\u0443 \u0441 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u043e\u043c \u0431\u0435\u0441\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u043e: \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c &#171;\u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435&#187; \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0438 \u043d\u0430\u0440\u0443\u0448\u0438\u0442\u044c \u043f\u0430\u043a\u0442.<\/p>\n<p>\u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432 \u0434\u043e\u043a\u0435\u0440\u0435 RabbitMq \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043e\u0431\u0449\u0430\u044e\u0442\u0441\u044f \u0441 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c:<\/p>\n<pre><code class=\"cs\">docker run --rm -d -p 15671:15671\/tcp -p 15672:15672\/tcp -p 25672:25672\/tcp  -p 4369:4369\/tcp -p 5671:5671\/tcp -p 5672:5672\/tcp rabbitmq:3-management<\/code><\/pre>\n<h3>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f  <\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f \u0441 \u043f\u043e\u043d\u044f\u0442\u0438\u044f\u043c\u0438 <em>consumer \/ provider<\/em> \u0438 <em>subscriber \/ publisher<\/em>, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0437\u0434\u0435\u0441\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u0430 \u0438 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0443\u0442\u0430\u0442\u044c<em>. <\/em>\u041a\u0430\u043a \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438,<em> <\/em>\u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u0445 Pact <em>consumer`\u043e\u043c<\/em> \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043a\u043b\u0438\u0435\u043d\u0442, \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044c API. \u0422\u0430\u043a\u0436\u0435 \u043f\u043e\u0434 \u044d\u0442\u0438\u043c \u043f\u043e\u043d\u044f\u0442\u0438\u0435\u043c \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a, \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438\u043b\u0438 <em>subscriber<\/em> \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u0445 \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u043d\u0430\u0434 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 <em>subscriber,<\/em> \u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <em>publisher. <\/em>\u0418\u0437 \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442, \u0447\u0442\u043e \u0432 \u043d\u0430\u0448\u0435\u0439 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438, \u0441\u0435\u0440\u0432\u0438\u0441 Demo.Provider \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (<em>publisher<\/em>) \u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f (<em>provider<\/em>), \u0430 \u0441\u0435\u0440\u0432\u0438\u0441 Demo.Consumer \u0441\u043b\u0443\u0436\u0438\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (<em>subscriber<\/em>) \u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u044f (<em>consumer<\/em>).<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432 \u043f\u0430\u043f\u043a\u0435 <em>Consumer.ContractTests\/RabbitMq<\/em> \u043a\u043b\u0430\u0441c CardOrderSatisfiedEventTests \u0438 \u043d\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 CardOrderSatisfiedEventTests<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cs\">public class CardOrderSatisfiedEventTests {     private readonly IMessagePactBuilderV4 _pactBuilder;     private const string ComType = \"RABBITMQ\";      public CardOrderSatisfiedEventTests(ITestOutputHelper testOutputHelper)     {         var pact = Pact.V4(consumer: \"Demo.Consumer\", provider: \"Demo.Provider\", new PactConfig         {             Outputters = new[] {new PactXUnitOutput(testOutputHelper)},             DefaultJsonSettings = new JsonSerializerOptions             {                 PropertyNameCaseInsensitive = true,                 PropertyNamingPolicy = JsonNamingPolicy.CamelCase             }         });         _pactBuilder = pact.WithMessageInteractions();     }      [Fact(DisplayName = \"Demo.Provider \u043f\u0440\u0438\u0441\u044b\u043b\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0438 \u043f\u0443\u0448 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \" +                         \"\u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\")]     public void CardOrderSatisfiedEvent_WhenModelCorrectAndShouldBePushed_SendsPush()     {         \/\/ Arrange         var message = new         {             UserId = Match.Type(\"rabbitmqUserId\"),             CardCode = Match.Integer(100),             ShouldBeNotified = true         };          _pactBuilder             .ExpectsToReceive($\"{ComType}: CardOrderSatisfiedEvent with push\")             .WithMetadata(\"exchangeName\", \"SpecialExchangeName\")             .WithMetadata(\"routingKey\", \"super-routing-key\")             .WithJsonContent(message)              \/\/ Act             .Verify&lt;CardOrderSatisfiedEvent>(msg =>             {                 \/\/ Assert                 \/\/ \u043c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 IConsumer.Handle \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430                 \/\/_consumerCardService.Verify(x => x.PushUser(msg), Times.Once);             });     }          [Fact(DisplayName = \"Demo.Provider \u043f\u0440\u0438\u0441\u044b\u043b\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0438 \u043f\u0443\u0448 \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \" +                         \"\u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\")]     public void CardOrderSatisfiedEvent_WhenModelCorrectAndShouldNotBePushed_DontSendPush()     {         \/\/ Arrange         var message = new         {             UserId = Match.Type(string.Empty),             CardCode = Match.Integer(100),             ShouldBeNotified = false         };          _pactBuilder             .ExpectsToReceive($\"{ComType}: CardOrderSatisfiedEvent no push\")             .WithMetadata(\"exchangeName\", \"SpecialExchangeName\")             .WithMetadata(\"routingKey\", \"super-routing-key\")             .WithJsonContent(message)              \/\/ Act             .Verify&lt;CardOrderSatisfiedEvent>(msg =>             {                 \/\/ Assert                 \/\/ \u043c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 IConsumer.Handle \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430                 \/\/_consumerCardService.Verify(x => x.PushUser(msg), Times.Never);             });     } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<ul>\n<li>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e <code>IPactBuilderV4<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>IMessagePactBuilderV4<\/code>, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u0430\u043a\u0442\u044b \u0434\u043b\u044f \u0441\u0438\u0441\u0442\u0435\u043c, \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0421\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0443\u0442\u0435\u043c \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 <code>WithMessageInteractions()<\/code>. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u0434 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043d\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0447\u0430\u0441\u0442\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u0434\u043b\u044f HTTP;<\/p>\n<\/li>\n<li>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>ExpectsToReceive()<\/code> \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 <code>UponReceiving()<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u0430, \u0430 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <code>WithJsonContent()<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 <code>WithMetadata()<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432\u0440\u043e\u0434\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432, \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u0438 \u043f\u0440\u043e\u0447\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0442\u0435\u0441\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043e\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u043c\u0435\u043d\u043d\u0438\u043a\u0430 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c SpecialExchangeName \u0438 \u0442\u043e\u043f\u0438\u043a\u0430 super-routing-key;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 <code>Verify<\/code> \u0432\u0441\u0435 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 pact.json, \u043d\u043e, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 HTTP \u0432\u0435\u0440\u0441\u0438\u0438, \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440, \u0430 \u0432 \u0441\u0435\u043a\u0446\u0438\u0438 <em>Assert<\/em> \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0446\u0435\u043b\u043e\u043c, \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f <em>event-driven<\/em> \u0441\u0438\u0441\u0442\u0435\u043c, Pact \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043e\u0442 \u043f\u043e\u043d\u044f\u0442\u0438\u044f \u0431\u0440\u043e\u043a\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0438 \u043d\u0435 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-379257","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/379257","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=379257"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/379257\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=379257"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=379257"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=379257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}