{"id":1254,"date":"2021-02-15T00:05:15","date_gmt":"2021-02-15T05:05:15","guid":{"rendered":"https:\/\/badecho.com\/?p=1254"},"modified":"2022-02-22T01:07:39","modified_gmt":"2022-02-22T06:07:39","slug":"segmenting-contracts-dispatchproxy","status":"publish","type":"post","link":"https:\/\/badecho.com\/index.php\/2021\/02\/15\/segmenting-contracts-dispatchproxy\/","title":{"rendered":"Segmenting Contracts With DispatchProxy in .NET 5.0"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"1024\" height=\"576\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/02\/NoMoreDynamicProxy-1024x576.png\" alt=\".NET 5.0 comes with some useful new functionality such as DispatchProxy, removing any need by me for Castle.Core.\" class=\"wp-image-1256\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/02\/NoMoreDynamicProxy-1024x576.png 1024w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/02\/NoMoreDynamicProxy-300x169.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/02\/NoMoreDynamicProxy-768x432.png 768w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/02\/NoMoreDynamicProxy-480x270.png 480w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/02\/NoMoreDynamicProxy.png 1200w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<h2>On the Nature of Segmenting Contracts<\/h2>\n\n\n\n<p>Not long after wrapping up the publishing of some of the foundational aspects of my Extensibility framework to my <a href=\"https:\/\/github.com\/BadEcho\/core\">Bad Echo Technologies repo<\/a>, I needed to start working on another side of the framework: support for my <code>IHostAdapter<\/code> interface. Implementations of this interface are responsible for establishing connections between a host and several routable plugin adapters that segment a common contract.<\/p>\n\n\n\n<p>What does it mean to segment a contract? Let&#8217;s, for instance, say we have an interface named <code>IContract<\/code>, with the methods <code>IContract.MethodOne<\/code> and <code>IContract.MethodTwo<\/code>. Then, let&#8217;s also assume we have two plugin assemblies, PluginA.dll and PluginB.dll, each with their own implementation of <code>IContract<\/code>. If we create a proxy that will route <code>IContract<\/code> method calls to PluginA.dll and PluginB.dll based on the particular method being called, then we have essentially segmented the <code>IContract<\/code> contract.<\/p>\n\n\n\n<h3>Segmenting IContract: An Illustration<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"600\" height=\"400\" src=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/02\/SegmentingAContract.png\" alt=\"Shows how a contract can be segmented so different methods will have their calls routed to different plugins.\" class=\"wp-image-1258\" srcset=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/02\/SegmentingAContract.png 600w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/02\/SegmentingAContract-300x200.png 300w, https:\/\/badecho.com\/wp-content\/uploads\/2021\/02\/SegmentingAContract-480x320.png 480w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><figcaption>Here we see IContract segmented: different method calls being routed to different plugins.<\/figcaption><\/figure><\/div>\n\n\n\n<p>The inspiration behind this concept came from one of the more significant kinds of creative drivers: attempting to sell a business proposition. In my first job out of college, I was working with a client\/server software solution that had a lot of market potential, but was plagued with horrible technological burdens. It was one of those pieces of software that indeed needed a complete rewrite, but of course I needed to convince the business owners to allow me to embark on such an endeavor. <\/p>\n\n\n\n<p>I was able to convince the owner to allow me to rewrite it by telling him I would develop a shiny new frontend client first, and only after that would I spend time redeveloping the backend. This would allow the company to begin to market and sell the shiny new frontend after a much shorter period of time than what would be required if we went about it the traditional way (making the backend first and then the frontend). So, essentially, a quicker capturing of profits from the rewrite effort.<\/p>\n\n\n\n<p>Because the new frontend would be operating against a brand new system service contract, I needed a way to reroute calls made to this new contract to the old backend. As the new backend was being developed, I would slowly shift responsibility for what ultimately processed service calls to it. In order to achieve all of this, I came up with this segmented contract approach.<\/p>\n\n\n\n<h2>On the Nature of Generating Proxy Objects<\/h2>\n\n\n\n<p>This article isn&#8217;t about the complete implementation of a contract segmentation solution, but rather how I went about generating the proxy objects that the solution requires while working on reorienting my treasure trove of code to run on top of .NET 5.0.<\/p>\n\n\n\n<p>Typically when we&#8217;re talking about proxy objects, we&#8217;re talking about them in the context of mocks, stubs, and\/or fakes. Fake objects adhering to some kind of interface that we configure at runtime to behave in a manner that aids in the process of testing a particular piece of code. What we&#8217;re doing here is very much a non-testing concern, but may benefit from the same bits of technology that testing-oriented frameworks that provide such objects use.<\/p>\n\n\n\n<p>That&#8217;s how I approached the problem originally, and it led me to end up using <a href=\"https:\/\/github.com\/castleproject\/Core\" target=\"_blank\" rel=\"noreferrer noopener\">Castle.Core<\/a> for my original solution. This is a very well known third-party library, and it makes available a runtime proxy generator known as <strong>Castle DynamicProxy<\/strong>. Using this library I satisfied the proxy-related concerns of contract segmentation by using Castle&#8217;s <code>ProxyGenerator<\/code> class and a custom <code>IInterceptor<\/code> implementation in order to reroute an interface&#8217;s method calls.<\/p>\n\n\n\n<p>It&#8217;s my goal to avoid excessive reliance on third-party libraries with the Bad Echo core frameworks library, the general-purpose library I&#8217;m building, but I decided to just swallow my pride a bit and add the Castle.Core NuGet package to the project. It was then that I saw that Castle.Core targets an older version of .NET Standard, and the amount of dependencies it wanted to bring along with it disturbed me slightly, making me uneasy enough to stop what I was doing.<\/p>\n\n\n\n<p>Another stumbling stone encountered. I started to think (and hope) about whether or not something was built into Microsoft&#8217;s latest .NET installment, namely .NET 5.0, that could help me generate proxy objects. And, to my surprise, there was!<\/p>\n\n\n\n<h2>Making a Routable Proxy with DispatchProxy<\/h2>\n\n\n\n<p>The <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.reflection.dispatchproxy?view=net-5.0\" target=\"_blank\" rel=\"noreferrer noopener\"><code>DispatchProxy<\/code><\/a> class is (from what I can tell) new to .NET Core and is a very nice way of going about generating proxy objects if we&#8217;re building on top of .NET 5.0. Looking at its source code, it is evident that it makes use of <code>Reflection.Emit<\/code>, just like Castle.Core does, to create a dynamic proxy at runtime. <\/p>\n\n\n\n<p>If a built-in solution satisfies requirements just as well as a third-party solution, I will 99% of the time gravitate towards adopting the built-in approach. That being said, I would very much be interested in measuring and analyzing performance differences between <code>DispatchProxy<\/code> and Castle.Core&#8217;s own proxy generating classes. That can be done some other day, however. I will give <code>DispatchProxy<\/code> the benefit of the doubt until then.<\/p>\n\n\n\n<p>It wasn&#8217;t long until some annoyances popped out at me when attempting to use <code>DispatchProxy<\/code> to create my routable proxy:<\/p>\n\n\n\n<ul><li>When generating the proxy type (the type deriving from <code>DispatchProxy<\/code>), it&#8217;s not possible to pass any arguments via the constructor. Since we need to provide it with a <code>IHostAdapter<\/code> to do the actual routing, we would need to instead feed it to the object by setting an exposed field.<\/li><li>A public parameterless constructor must be exposed on the proxy type in order for it to be instantiated properly.<\/li><\/ul>\n\n\n\n<p>The above issues make it impossible to force construction of our proxy type so it can only occur through the use of a public static factory method, which would ensure that the proxy type was fully initialized with the <code>IHostAdapter<\/code> loaded into it; specifically, because we&#8217;re required to have a public constructor. That means a consumer could initialize it by invoking the public constructor and have a bunk proxy object.<\/p>\n\n\n\n<p>There&#8217;s really no way around this, the proxy type itself <em>must<\/em> be public, so I can&#8217;t have an internal or private object that I create and make available by a public, sanitized type. It&#8217;s a minor problem, and we do the best that we can in this situation by at least throwing an exception to alert a consumer that they initialized the type wrong.<\/p>\n\n\n\n<p>That being said, let&#8217;s take a look at <code>RoutableProxy<\/code>, based on .NET 5.0&#8217;s <code>DispatchProxy<\/code>.<\/p>\n\n\n\n<h3>RoutableProxy Class<\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/\/ &lt;summary&gt;\n\/\/\/ Provides a proxy object that handles method dispatch by routing segmented contract method calls\n\/\/\/ to the call-routable plugins pointed to by a provided &lt;see cref=&quot;IHostAdapter&quot;\/&gt; instance.\n\/\/\/ &lt;\/summary&gt;\n\/\/\/ &lt;suppresions&gt;\n\/\/\/ ReSharper disable EmptyConstructor\n\/\/\/ &lt;\/suppresions&gt;\npublic class RoutableProxy : DispatchProxy\n{\n    private IHostAdapter? _adapter;\n\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ Initializes a new instance of the &lt;see cref=&quot;RoutableProxy&quot;\/&gt; class.\n    \/\/\/ &lt;\/summary&gt;\n    \/\/\/ &lt;remarks&gt;\n    \/\/\/ Consumers should not initialize this object by calling this constructor directly. It exists\n    \/\/\/ only to fulfill requirements of &lt;see cref=&quot;DispatchProxy&quot;\/&gt;.\n    \/\/\/ &lt;\/remarks&gt;\n    public RoutableProxy()\n    { }\n\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ Creates an instance of &lt;typeparamref name=&quot;T&quot;\/&gt; that will route method calls through the\n    \/\/\/ provided host adapter.\n    \/\/\/ &lt;\/summary&gt;\n    \/\/\/ &lt;param name=&quot;adapter&quot;&gt;The host adapter to route calls through.&lt;\/param&gt;\n    \/\/\/ &lt;returns&gt;\n    \/\/\/ An object instance implementing &lt;typeparamref name=&quot;T&quot;\/&gt; that will route calls through\n    \/\/\/ &lt;c&gt;adapter&lt;\/c&gt;.\n    \/\/\/ &lt;\/returns&gt;\n    \/\/\/ &lt;typeparam name=&quot;T&quot;&gt;\n    \/\/\/ The segmented contract type whose calls will be routed through the proxy.\n    \/\/\/ &lt;\/typeparam&gt;\n    public static T Create&lt;T&gt;(IHostAdapter adapter)\n        where T : class\n    {\n        if (adapter == null) \n            throw new ArgumentNullException(nameof(adapter));\n\n        object proxy = Create&lt;T, RoutableProxy&gt;();\n        var routableProxy = (RoutableProxy)proxy;\n\n        routableProxy._adapter = adapter;\n\n        return (T) proxy;\n    }\n\n    \/\/\/ &lt;inheritdoc\/&gt;\n    protected override object? Invoke(MethodInfo? targetMethod, object?[]? args)\n    {\n        if (_adapter == null)\n            throw new InvalidOperationException(Strings.RoutableProxyNotInitializedCorrectly);\n        \n        \/\/ It is unclear to me as to how targetMethod ever ends up being null.\n        \/\/ Exception won't be thrown since, by virtue of the method signature, we must support null\n        \/\/ values for this argument.\n        if (targetMethod == null)\n        {\n            Logger.Warning(Strings.RoutableProxyNullMethodInfo);\n            return null;\n        }\n\n        object contractImpl = _adapter.Route(targetMethod.Name);\n\n        return targetMethod.Invoke(contractImpl, args);\n    }\n}\n<\/pre>\n\n\n<p>We now have the means to segment a contract of our choice. Let&#8217;s take a peek at some sample usage of this type to segment the <code>IContract<\/code> type we discussed earlier.<\/p>\n\n\n\n<h3>Segmenting IContract With RoutableProxy<\/h3>\n\n\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic void SegmentContract(IHostAdapter adapter)\n{\n    IContract proxy = RoutableProxy.Create&lt;IContract&gt;(adapter);\n\n    \/\/ This will call IContract.MethodOne in PluginA.dll.\n    proxy.MethodOne();\n\n    \/\/ This will call IContract.MethodTwo in PluginB.dll.\n    proxy.MethodTwo();\n}\n<\/pre>\n\n\n<p>There you go, a nice segmented contract.<\/p>\n\n\n\n<h2>How Does IHostAdapter Work?<\/h2>\n\n\n\n<p>That&#8217;s outside the scope of this article, but maybe I&#8217;ll write it about it in the future. Until then, pay attention to the <a href=\"https:\/\/github.com\/BadEcho\/core\" target=\"_blank\" rel=\"noreferrer noopener\">Bad Echo Technologies repo<\/a> to see how it works and how it gets used with <code>RoutableProxy<\/code>.<\/p>\n\n\n\n<p>As always, take care and thank you for your time in reading this.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>On the Nature of Segmenting Contracts Not long after wrapping up the publishing of some of the foundational aspects of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[10],"tags":[41,42,56],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\r\n<title>Segmenting Contracts With DispatchProxy in .NET 5.0 - omni&#039;s hackpad<\/title>\r\n<meta name=\"description\" content=\"Shows how to take advantage of proxy objects that are built into .NET 5.0 to segment a contract, removing a dependency on Castle.Core.\" \/>\r\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\r\n<link rel=\"canonical\" href=\"https:\/\/badecho.com\/index.php\/2021\/02\/15\/segmenting-contracts-dispatchproxy\/\" \/>\r\n<meta property=\"og:locale\" content=\"en_US\" \/>\r\n<meta property=\"og:type\" content=\"article\" \/>\r\n<meta property=\"og:title\" content=\"Segmenting Contracts With DispatchProxy in .NET 5.0 - omni&#039;s hackpad\" \/>\r\n<meta property=\"og:description\" content=\"Shows how to take advantage of proxy objects that are built into .NET 5.0 to segment a contract, removing a dependency on Castle.Core.\" \/>\r\n<meta property=\"og:url\" content=\"https:\/\/badecho.com\/index.php\/2021\/02\/15\/segmenting-contracts-dispatchproxy\/\" \/>\r\n<meta property=\"og:site_name\" content=\"omni&#039;s hackpad\" \/>\r\n<meta property=\"article:published_time\" content=\"2021-02-15T05:05:15+00:00\" \/>\r\n<meta property=\"article:modified_time\" content=\"2022-02-22T06:07:39+00:00\" \/>\r\n<meta property=\"og:image\" content=\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/02\/NoMoreDynamicProxy-1024x576.png\" \/>\r\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\r\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/badecho.com\/#website\",\"url\":\"https:\/\/badecho.com\/\",\"name\":\"omni&#039;s hackpad\",\"description\":\"Game Code Disassembly. Omnified Modification. Madness.\",\"publisher\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/badecho.com\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/02\/15\/segmenting-contracts-dispatchproxy\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/badecho.com\/wp-content\/uploads\/2021\/02\/NoMoreDynamicProxy.png\",\"width\":1200,\"height\":675,\"caption\":\".NET 5.0 comes with some useful new functionality such as DispatchProxy, removing any need by me for Castle.Core.\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/02\/15\/segmenting-contracts-dispatchproxy\/#webpage\",\"url\":\"https:\/\/badecho.com\/index.php\/2021\/02\/15\/segmenting-contracts-dispatchproxy\/\",\"name\":\"Segmenting Contracts With DispatchProxy in .NET 5.0 - omni&#039;s hackpad\",\"isPartOf\":{\"@id\":\"https:\/\/badecho.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/02\/15\/segmenting-contracts-dispatchproxy\/#primaryimage\"},\"datePublished\":\"2021-02-15T05:05:15+00:00\",\"dateModified\":\"2022-02-22T06:07:39+00:00\",\"description\":\"Shows how to take advantage of proxy objects that are built into .NET 5.0 to segment a contract, removing a dependency on Castle.Core.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/badecho.com\/index.php\/2021\/02\/15\/segmenting-contracts-dispatchproxy\/\"]}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/02\/15\/segmenting-contracts-dispatchproxy\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/02\/15\/segmenting-contracts-dispatchproxy\/#webpage\"},\"author\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"headline\":\"Segmenting Contracts With DispatchProxy in .NET 5.0\",\"datePublished\":\"2021-02-15T05:05:15+00:00\",\"dateModified\":\"2022-02-22T06:07:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/02\/15\/segmenting-contracts-dispatchproxy\/#webpage\"},\"publisher\":{\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\"},\"image\":{\"@id\":\"https:\/\/badecho.com\/index.php\/2021\/02\/15\/segmenting-contracts-dispatchproxy\/#primaryimage\"},\"keywords\":\".NET,C#,DispatchProxy\",\"articleSection\":\"General Dev\",\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/badecho.com\/#\/schema\/person\/3de67496328be7ae6e1f52faf582e9d2\",\"name\":\"Matt Weber\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/badecho.com\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/7e345ac2708b3a41c7bd70a4a0440d41?s=96&d=mm&r=g\",\"caption\":\"Matt Weber\"},\"logo\":{\"@id\":\"https:\/\/badecho.com\/#personlogo\"}}]}<\/script>\r\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/1254"}],"collection":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/comments?post=1254"}],"version-history":[{"count":7,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/1254\/revisions"}],"predecessor-version":[{"id":2351,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/posts\/1254\/revisions\/2351"}],"wp:attachment":[{"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/media?parent=1254"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/categories?post=1254"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/badecho.com\/index.php\/wp-json\/wp\/v2\/tags?post=1254"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}