{"id":1746,"date":"2023-05-06T21:07:11","date_gmt":"2023-05-06T14:07:11","guid":{"rendered":"https:\/\/csharptutorial.net\/?page_id=1746"},"modified":"2023-05-13T15:02:15","modified_gmt":"2023-05-13T08:02:15","slug":"csharp-proxy","status":"publish","type":"page","link":"https:\/\/www.csharptutorial.net\/csharp-design-patterns\/csharp-proxy\/","title":{"rendered":"C# Proxy"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn about the C# Proxy design pattern and how to use a proxy object to control access to a real object.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction to the C# Proxy design pattern<\/h2>\n\n\n\n<p>The Proxy pattern is a structural design pattern that allows you to use a proxy object to control access to an actual object and to provide additional functionality without modifying the actual object.<\/p>\n\n\n\n<p>For example, the proxy object may add caching, logging, or authorization service to the actual object. In some cases, the actual object creation is expensive, the proxy object can help improve the performance by delaying the creation of the actual object until it is actually needed. <\/p>\n\n\n\n<p>The following UML diagram illustrates the Proxy design pattern:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"https:\/\/csharptutorial.net\/wp-content\/uploads\/2023\/05\/CSharp-Proxy.svg\" alt=\"C# Proxy\" class=\"wp-image-1747\"\/><\/figure>\n<\/div>\n\n\n<p>Here are the participants in the Proxy pattern:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Subject<\/code> defines the common <a href=\"https:\/\/csharptutorial.net\/csharp-tutorial\/csharp-interface\/\">interface<\/a> for both <code><code>RealSubject<\/code><\/code> and <code>Proxy<\/code> so that you can substitute the <code><code>RealSubject<\/code><\/code> by the <code>Proxy<\/code>.<\/li>\n\n\n\n<li><code>RealSubject<\/code> defines the real object that the <code>Proxy<\/code> substitutes.<\/li>\n\n\n\n<li><code>Proxy<\/code> maintains a <code><code><code>RealSubject<\/code><\/code><\/code> object so that it can call the methods of the <code><code><code>RealSubject<\/code><\/code><\/code> when needed. Before or after calling the methods of the <code><code><code>RealSubject<\/code><\/code><\/code> object, the <code>Proxy<\/code> may add more functionality such as caching or logging.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">C# Proxy pattern example<\/h2>\n\n\n\n<p>This C# program demonstrates how to use the Proxy pattern to cache API requests using <code>HttpClient<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">using<\/span> System.Text.Json;\n\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">ProxyPattern<\/span>;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Post<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span> UserId\n    {\n        <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>;\n    }\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span> Id\n    {\n        <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>;\n    }\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span>? Title\n    {\n        <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>;\n    }\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span>? Body\n    {\n        <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">string<\/span> <span class=\"hljs-title\">ToString<\/span>(<span class=\"hljs-params\"><\/span>)<\/span> =&gt; <span class=\"hljs-string\">$\"&lt;<span class=\"hljs-subst\">{Id}<\/span>&gt; - <span class=\"hljs-subst\">{Title}<\/span>\"<\/span>;\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">IPostAPI<\/span>\n{\n    Task&lt;Post?&gt; GetPost(<span class=\"hljs-keyword\">int<\/span> postId);\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">JSONPlaceholderAPI<\/span> : <span class=\"hljs-title\">IPostAPI<\/span>\n{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> HttpClient _httpClient;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">JSONPlaceholderAPI<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>\n    {\n        _httpClient = <span class=\"hljs-keyword\">new<\/span> HttpClient();\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">async<\/span> Task&lt;Post?&gt; GetPost(<span class=\"hljs-keyword\">int<\/span> postId)\n    {\n        <span class=\"hljs-keyword\">var<\/span> response = <span class=\"hljs-keyword\">await<\/span> _httpClient.GetAsync(<span class=\"hljs-string\">$\"https:\/\/jsonplaceholder.typicode.com\/posts\/<span class=\"hljs-subst\">{postId}<\/span>\"<\/span>);\n\n        <span class=\"hljs-keyword\">if<\/span> (!response.IsSuccessStatusCode)\n        {\n            <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> Exception(<span class=\"hljs-string\">$\"Failed to retrieve post <span class=\"hljs-subst\">{postId}<\/span> from API: <span class=\"hljs-subst\">{response.ReasonPhrase}<\/span>\"<\/span>);\n        }\n\n        <span class=\"hljs-keyword\">var<\/span> json = <span class=\"hljs-keyword\">await<\/span> response.Content.ReadAsStringAsync();\n\n        <span class=\"hljs-keyword\">var<\/span> options = <span class=\"hljs-keyword\">new<\/span> JsonSerializerOptions()\n        {\n            PropertyNameCaseInsensitive = <span class=\"hljs-literal\">true<\/span>\n        };\n\n        <span class=\"hljs-keyword\">var<\/span> post = JsonSerializer.Deserialize&lt;Post?&gt;(json, options);\n        <span class=\"hljs-keyword\">return<\/span> post;\n    }\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">JSONPlaceholderAPIProxy<\/span> : <span class=\"hljs-title\">IPostAPI<\/span>\n{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> IPostAPI _postAPI;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> Dictionary&lt;<span class=\"hljs-keyword\">int<\/span>, Post&gt; _postCache;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">JSONPlaceholderAPIProxy<\/span>(<span class=\"hljs-params\">IPostAPI postAPI<\/span>)<\/span>\n    {\n        _postAPI = postAPI;\n        _postCache = <span class=\"hljs-keyword\">new<\/span> Dictionary&lt;<span class=\"hljs-keyword\">int<\/span>, Post&gt;();\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">async<\/span> Task&lt;Post?&gt; GetPost(<span class=\"hljs-keyword\">int<\/span> postId)\n    {\n        <span class=\"hljs-keyword\">if<\/span> (_postCache.ContainsKey(postId))\n        {\n            Console.WriteLine(<span class=\"hljs-string\">$\"Retrieving post <span class=\"hljs-subst\">{postId}<\/span> from cache.\"<\/span>);\n            <span class=\"hljs-keyword\">return<\/span> _postCache&#91;postId];\n        }\n\n        <span class=\"hljs-keyword\">var<\/span> post = <span class=\"hljs-keyword\">await<\/span> _postAPI.GetPost(postId);\n        _postCache&#91;postId] = post;\n        <span class=\"hljs-keyword\">return<\/span> post;\n    }\n}\n\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Program<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">async<\/span> Task <span class=\"hljs-title\">Main<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">var<\/span> api = <span class=\"hljs-keyword\">new<\/span> JSONPlaceholderAPI();\n        <span class=\"hljs-keyword\">var<\/span> apiProxy = <span class=\"hljs-keyword\">new<\/span> JSONPlaceholderAPIProxy(api);\n\n        <span class=\"hljs-comment\">\/\/ Get post 1<\/span>\n        <span class=\"hljs-keyword\">var<\/span> post1 = <span class=\"hljs-keyword\">await<\/span> apiProxy.GetPost(<span class=\"hljs-number\">1<\/span>);\n        Console.WriteLine(<span class=\"hljs-string\">$\"Post 1: <span class=\"hljs-subst\">{post1}<\/span>\"<\/span>);\n\n        <span class=\"hljs-comment\">\/\/ Get post 1 again - should retrieve from cache<\/span>\n        <span class=\"hljs-keyword\">var<\/span> post1Cached = <span class=\"hljs-keyword\">await<\/span> apiProxy.GetPost(<span class=\"hljs-number\">1<\/span>);\n        Console.WriteLine(<span class=\"hljs-string\">$\"Post 1 (cached): <span class=\"hljs-subst\">{post1Cached}<\/span>\"<\/span>);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">Post 1: &lt;1&gt; - sunt aut facere repellat provident occaecati excepturi optio reprehenderit\nRetrieving post 1 from cache.\nPost 1 (cached): &lt;1&gt; - sunt aut facere repellat provident occaecati excepturi optio reprehenderit<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>How it works.<\/p>\n\n\n\n<p>First, define the <code>Post<\/code> class that has the <code>UserId<\/code>, <code>Id<\/code>, <code>Title<\/code>, and <code>Body<\/code> properties. The <code>ToString()<\/code> method returns the string representation of a post:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Post<\/span>\n{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span> UserId\n    {\n        <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>;\n    }\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">int<\/span> Id\n    {\n        <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>;\n    }\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span>? Title\n    {\n        <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>;\n    }\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">string<\/span>? Body\n    {\n        <span class=\"hljs-keyword\">get<\/span>; <span class=\"hljs-keyword\">set<\/span>;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">string<\/span> <span class=\"hljs-title\">ToString<\/span>(<span class=\"hljs-params\"><\/span>)<\/span> =&gt; <span class=\"hljs-string\">$\"&lt;<span class=\"hljs-subst\">{Id}<\/span>&gt; - <span class=\"hljs-subst\">{Title}<\/span>\"<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Next, define the <code>IPostAPI<\/code> interface that has a <code>GetPost()<\/code> method which returns a Post by <code>PostId<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">IPostAPI<\/span>\n{\n    Task&lt;Post?&gt; GetPost(<span class=\"hljs-keyword\">int<\/span> postId);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>IPostAPI<\/code> serves as the <code>Subject<\/code> in the above UML diagram.<\/p>\n\n\n\n<p>Then, define the <code><code>JSONPlaceholderAPI<\/code><\/code> that implements the <code>IPostAPI<\/code> interface. The <code><code>JSONPlaceholderAPI<\/code><\/code> uses the <code>HttpClient<\/code> to call API from <code>https:\/\/jsonplaceholder.typicode.com\/posts\/1\/<\/code>, where 1 is the post id:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">JSONPlaceholderAPI<\/span> : <span class=\"hljs-title\">IPostAPI<\/span>\n{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> HttpClient _httpClient;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">JSONPlaceholderAPI<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>\n    {\n        _httpClient = <span class=\"hljs-keyword\">new<\/span> HttpClient();\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">async<\/span> Task&lt;Post?&gt; GetPost(<span class=\"hljs-keyword\">int<\/span> postId)\n    {\n        <span class=\"hljs-keyword\">var<\/span> response = <span class=\"hljs-keyword\">await<\/span> _httpClient.GetAsync(<span class=\"hljs-string\">$\"https:\/\/jsonplaceholder.typicode.com\/posts\/<span class=\"hljs-subst\">{postId}<\/span>\"<\/span>);\n\n        <span class=\"hljs-keyword\">if<\/span> (!response.IsSuccessStatusCode)\n        {\n            <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> Exception(<span class=\"hljs-string\">$\"Failed to retrieve post <span class=\"hljs-subst\">{postId}<\/span> from API: <span class=\"hljs-subst\">{response.ReasonPhrase}<\/span>\"<\/span>);\n        }\n\n        <span class=\"hljs-keyword\">var<\/span> json = <span class=\"hljs-keyword\">await<\/span> response.Content.ReadAsStringAsync();\n\n        <span class=\"hljs-keyword\">var<\/span> options = <span class=\"hljs-keyword\">new<\/span> JsonSerializerOptions()\n        {\n            PropertyNameCaseInsensitive = <span class=\"hljs-literal\">true<\/span>\n        };\n\n        <span class=\"hljs-keyword\">var<\/span> post = JsonSerializer.Deserialize&lt;Post?&gt;(json, options);\n        <span class=\"hljs-keyword\">return<\/span> post;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>JSONPlaceholderAPI<\/code> class serves as the <code>RealSubject<\/code>.<\/p>\n\n\n\n<p>After that, define the <code>JSONPlaceholderAPIProxy<\/code> class that implements the <code>IPostAPI<\/code>. The <code>JSONPlaceholderAPIProxy<\/code> acts as a <code>Proxy<\/code> object of the <code>JSONPlaceholderAPI<\/code>. It caches a <code>Post<\/code> by <code>postId<\/code> so that if you request the same <code>postId <\/code>again, it&#8217;ll return the <code>Post<\/code> from the cache instead of calling the API:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">JSONPlaceholderAPIProxy<\/span> : <span class=\"hljs-title\">IPostAPI<\/span>\n{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> IPostAPI _postAPI;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> Dictionary&lt;<span class=\"hljs-keyword\">int<\/span>, Post&gt; _postCache;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">JSONPlaceholderAPIProxy<\/span>(<span class=\"hljs-params\">IPostAPI postAPI<\/span>)<\/span>\n    {\n        _postAPI = postAPI;\n        _postCache = <span class=\"hljs-keyword\">new<\/span> Dictionary&lt;<span class=\"hljs-keyword\">int<\/span>, Post&gt;();\n    }\n\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">async<\/span> Task&lt;Post?&gt; GetPost(<span class=\"hljs-keyword\">int<\/span> postId)\n    {\n        <span class=\"hljs-keyword\">if<\/span> (_postCache.ContainsKey(postId))\n        {\n            Console.WriteLine(<span class=\"hljs-string\">$\"Retrieving post <span class=\"hljs-subst\">{postId}<\/span> from cache.\"<\/span>);\n            <span class=\"hljs-keyword\">return<\/span> _postCache&#91;postId];\n        }\n\n        <span class=\"hljs-keyword\">var<\/span> post = <span class=\"hljs-keyword\">await<\/span> _postAPI.GetPost(postId);\n        _postCache&#91;postId] = post;\n        <span class=\"hljs-keyword\">return<\/span> post;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Finally, create the <code>JSONPlaceholderAPI<\/code> object and pass it to the constructor of the <code>JSONPlaceholderAPIProxy<\/code> object. The program requests the post with id 1 twice from the <code>JSONPlaceholderAPIProxy<\/code> object. Because of the caching, the second request does not call the API but returns the post from the cache.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Program<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">async<\/span> Task <span class=\"hljs-title\">Main<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">var<\/span> api = <span class=\"hljs-keyword\">new<\/span> JSONPlaceholderAPI();\n        <span class=\"hljs-keyword\">var<\/span> apiProxy = <span class=\"hljs-keyword\">new<\/span> JSONPlaceholderAPIProxy(api);\n\n        <span class=\"hljs-comment\">\/\/ Get post 1<\/span>\n        <span class=\"hljs-keyword\">var<\/span> post1 = <span class=\"hljs-keyword\">await<\/span> apiProxy.GetPost(<span class=\"hljs-number\">1<\/span>);\n        Console.WriteLine(<span class=\"hljs-string\">$\"Post 1: <span class=\"hljs-subst\">{post1}<\/span>\"<\/span>);\n\n        <span class=\"hljs-comment\">\/\/ Get post 1 again - should retrieve from cache<\/span>\n        <span class=\"hljs-keyword\">var<\/span> post1Cached = <span class=\"hljs-keyword\">await<\/span> apiProxy.GetPost(<span class=\"hljs-number\">1<\/span>);\n        Console.WriteLine(<span class=\"hljs-string\">$\"Post 1 (cached): <span class=\"hljs-subst\">{post1Cached}<\/span>\"<\/span>);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use the Proxy design pattern to control access to an actual object and to extend its functionality without modifying the actual object directly.<\/li>\n<\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"1746\"\n\t\t\t\tdata-post-url=\"https:\/\/www.csharptutorial.net\/csharp-design-patterns\/csharp-proxy\/\"\n\t\t\t\tdata-post-title=\"C# Proxy\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"1746\"\n\t\t\t\tdata-post-url=\"https:\/\/www.csharptutorial.net\/csharp-design-patterns\/csharp-proxy\/\"\n\t\t\t\tdata-post-title=\"C# Proxy\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\n\t\t\t<button class=\"btn btn-primary wth-btn-submit\">Send<\/button>\n\t\t\t<button class=\"btn wth-btn-cancel\">Cancel<\/button>\n\t\t\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Summary: in this tutorial, you&#8217;ll learn about the C# Proxy design pattern and how to use a proxy object to control access to a real object. Introduction to the C# Proxy design pattern The Proxy pattern is a structural design pattern that allows you to use a proxy object to control access to an actual [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1441,"menu_order":19,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1746","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1746","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/comments?post=1746"}],"version-history":[{"count":4,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1746\/revisions"}],"predecessor-version":[{"id":1820,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1746\/revisions\/1820"}],"up":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/1441"}],"wp:attachment":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/media?parent=1746"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}