<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Cuemon for .NET]]></title><description><![CDATA[Thoughts, stories and ideas.]]></description><link>https://www.cuemon.net/blog/</link><image><url>https://www.cuemon.net/blog/favicon.png</url><title>Cuemon for .NET</title><link>https://www.cuemon.net/blog/</link></image><generator>Ghost 4.32</generator><lastBuildDate>Sat, 18 Apr 2026 01:35:21 GMT</lastBuildDate><atom:link href="https://www.cuemon.net/blog/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Time goes by .. so fast!]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>We all know the two value types <code>DateTime</code> and <code>TimeSpan</code>.</p>
<p>With this article, I will write about two simple (yet, very neat) value types, that has been part of the Cuemon family for a very long time (pun intended) and supplement the above mentioned almost to perfection; they are <code>DateSpan</code></p>]]></description><link>https://www.cuemon.net/blog/time-goes-by-so-fast/</link><guid isPermaLink="false">60883e03c883260001fb8ff2</guid><category><![CDATA[datetime]]></category><category><![CDATA[timespan]]></category><category><![CDATA[datespan]]></category><category><![CDATA[timerange]]></category><category><![CDATA[dotnet]]></category><category><![CDATA[dotnetcore]]></category><category><![CDATA[dotnetstandard]]></category><category><![CDATA[csharp]]></category><category><![CDATA[calendar]]></category><category><![CDATA[timeperiod]]></category><dc:creator><![CDATA[Michael Mortensen]]></dc:creator><pubDate>Mon, 01 Oct 2018 21:36:15 GMT</pubDate><media:content url="https://www.cuemon.net/blog/content/images/2018/10/RTI00790.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://www.cuemon.net/blog/content/images/2018/10/RTI00790.jpg" alt="Time goes by .. so fast!"><p>We all know the two value types <code>DateTime</code> and <code>TimeSpan</code>.</p>
<p>With this article, I will write about two simple (yet, very neat) value types, that has been part of the Cuemon family for a very long time (pun intended) and supplement the above mentioned almost to perfection; they are <code>DateSpan</code> and <code>TimeRange</code>.</p>
<p>After the v.6.0.0 release of Cuemon for .NET, <code>TimeRange</code> was changed to a class an renamed to <code>DateTimeRange</code> that inherits from the abstract class named <a href="https://docs.cuemon.net/api/dotnet/Cuemon.Range-1.html">Range{T}</a>. Also, the former <code>TimeRange</code> was added - but covering a range between two TimeSpan value types.</p>
<h1 id="datespan">DateSpan</h1>
<p>With this struct I was aiming for a simple way to calculate the interval between two <code>DateTime</code> values. Although it seemed like a simple task, it was not without challenges as I had to think about <code>CultureInfo</code> and <code>Calendar</code> at the same time.</p>
<p>Just looking through the code while writing this, I am sure I would refactor most, as it dates back to 2010 (with some modifications over the years).</p>
<p><mark>Update: the code was refactored with the release of Cuemon for .NET v6.0.0 &#x1F389;</mark></p>
<p>Anyway, here is a sample on how to calculate the interval from January 1st this year up till today (2018-10-01):</p>
<pre style="font-family:Consolas;font-size:13px;color:gainsboro;background:#1e1e1e;"><span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">void</span>&#xA0;DateSpanExample()
{
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">var</span>&#xA0;ds&#xA0;<span style="color:#b4b4b4;">=</span>&#xA0;<span style="color:#569cd6;">new</span>&#xA0;<span style="color:#4ec9b0;">DateSpan</span>(<span style="color:#569cd6;">new</span>&#xA0;<span style="color:#4ec9b0;">DateTime</span>(<span style="color:#b5cea8;">2018</span>,&#xA0;<span style="color:#b5cea8;">1</span>,&#xA0;<span style="color:#b5cea8;">1</span>),&#xA0;<span style="color:#4ec9b0;">DateTime</span><span style="color:#b4b4b4;">.</span>Today);
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#4ec9b0;">Trace</span><span style="color:#b4b4b4;">.</span>WriteLine(<span style="color:#d69d85;">$&quot;</span>{ds<span style="color:#b4b4b4;">.</span>Years}<span style="color:#d69d85;">&#xA0;year&quot;</span>);
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#4ec9b0;">Trace</span><span style="color:#b4b4b4;">.</span>WriteLine(<span style="color:#d69d85;">$&quot;</span>{ds<span style="color:#b4b4b4;">.</span>Months}<span style="color:#d69d85;">&#xA0;months&quot;</span>);
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#4ec9b0;">Trace</span><span style="color:#b4b4b4;">.</span>WriteLine(<span style="color:#d69d85;">$&quot;</span>{ds<span style="color:#b4b4b4;">.</span>GetWeeks()}<span style="color:#d69d85;">&#xA0;weeks&quot;</span>);
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#4ec9b0;">Trace</span><span style="color:#b4b4b4;">.</span>WriteLine(<span style="color:#d69d85;">$&quot;</span>{ds<span style="color:#b4b4b4;">.</span>TotalDays}<span style="color:#d69d85;">&#xA0;days&quot;</span>);
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#4ec9b0;">Trace</span><span style="color:#b4b4b4;">.</span>WriteLine(<span style="color:#d69d85;">$&quot;</span>{ds<span style="color:#b4b4b4;">.</span>TotalHours}<span style="color:#d69d85;">&#xA0;hours&quot;</span>);
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#4ec9b0;">Trace</span><span style="color:#b4b4b4;">.</span>WriteLine(<span style="color:#d69d85;">$&quot;</span>{ds<span style="color:#b4b4b4;">.</span>TotalMinutes<span style="color:#80ff80;">:</span><span style="color:#80ff80;">N0</span>}<span style="color:#d69d85;">&#xA0;minutes&quot;</span>);
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#4ec9b0;">Trace</span><span style="color:#b4b4b4;">.</span>WriteLine(<span style="color:#d69d85;">$&quot;</span>{ds<span style="color:#b4b4b4;">.</span>TotalSeconds<span style="color:#80ff80;">:</span><span style="color:#80ff80;">N0</span>}<span style="color:#d69d85;">&#xA0;seconds&quot;</span>);
}</pre>
<p>This writes out the following output:</p>
<pre><code class="language-dotnetcli">Debug Trace:
0 year
10 months
40 weeks
273 days
6552 hours
393.120 minutes
23.587.200 seconds
</code></pre>
<p>
</p><h1 id="datetimerange">DateTimeRange</h1>
<p>Similiar to <code>DateSpan</code>, this class also represents a period of time between two <code>DateTime</code> values. However, the representation is pure and does not contain any code that can perform complex calculations as the case is with the <code>DateSpan</code> counterpart.</p>
<p>Here is a sample on how to define a period of time ranging from January 1st this year up till today (2021-05-03):</p>
<pre style="font-family:Consolas;font-size:13px;color:gainsboro;background:#1e1e1e;"><span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">void</span>&#xA0;<span style="color:#dcdcaa;">DateTimeRangeExample</span>()
{
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">var</span>&#xA0;<span style="color:#9cdcfe;">dtr</span>&#xA0;<span style="color:#b4b4b4;">=</span>&#xA0;<span style="color:#569cd6;">new</span>&#xA0;DateTimeRange(<span style="color:#569cd6;">new</span>&#xA0;DateTime(<span style="color:#b5cea8;">2021</span>,&#xA0;<span style="color:#b5cea8;">1</span>,&#xA0;<span style="color:#b5cea8;">1</span>),&#xA0;DateTime<span style="color:#b4b4b4;">.</span>Today);
&#xA0;&#xA0;&#xA0;&#xA0;Trace<span style="color:#b4b4b4;">.</span>WriteLine(dtr);
}</pre>
<p>This writes out the following output:</p>
<pre><code class="language-dotnetcli">Debug Trace:
A duration of 122.00:00:00 between 2021-01-01T00:00:00 and 2021-05-03T00:00:00.
</code></pre>
<p>
</p><h1 id="timerange">TimeRange</h1>
<p>Similiar to <code>DateTimeRange</code>, this class represents a period of time between two <code>TimeSpan</code> values.</p>
<pre style="font-family:Consolas;font-size:13px;color:gainsboro;background:#1e1e1e;"><span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">void</span>&#xA0;<span style="color:#dcdcaa;">TimeRangeExample</span>()
{
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">var</span>&#xA0;<span style="color:#9cdcfe;">tr</span>&#xA0;<span style="color:#b4b4b4;">=</span>&#xA0;<span style="color:#569cd6;">new</span>&#xA0;TimeRange(TimeSpan<span style="color:#b4b4b4;">.</span>FromHours(<span style="color:#b5cea8;">4</span>),&#xA0;TimeSpan<span style="color:#b4b4b4;">.</span>FromHours(<span style="color:#b5cea8;">6</span>));
&#xA0;&#xA0;&#xA0;&#xA0;Trace<span style="color:#b4b4b4;">.</span>WriteLine(tr);
}</pre>
<pre><code class="language-dotnetcli">Debug Trace:
A duration of 00.02:00:00 between 04:00:00 and 06:00:00.
</code></pre>
<h2 id="closingwords">Closing Words</h2>
<p>This was a brief article of the struct <code>DateSpan</code> and the two classes <code>DateTimeRange</code> and <code>TimeRange</code>. I hope it brought something to mind and that you can see the value it might add to your projects.</p>
<p>Never the less; code with passion &#x1F525;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[ASP.NET Core: Middleware by Abstraction]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>With ASP.NET Core the primary way of creating middleware components is by using <strong>convention-based</strong> activation logic. A secondary way is to use factory-based implementation that was added with two interfaces, <code>IMiddlewareFactory</code> and <code>IMiddleware</code>.</p>
<p>An example of convention-based middleware class looks like this:</p>
<pre style="font-family:Consolas;font-size:13px;color:gainsboro;background:#1e1e1e;"><span style="color:#57a64a;">//&#xA0;You&#xA0;may&#xA0;need&#xA0;</span></pre>]]></description><link>https://www.cuemon.net/blog/asp-net-core-middleware-by-abstraction/</link><guid isPermaLink="false">60883e03c883260001fb8ff1</guid><category><![CDATA[dotnet]]></category><category><![CDATA[dotnetcore]]></category><category><![CDATA[dotnetstandard]]></category><category><![CDATA[csharp]]></category><category><![CDATA[aspnetcore]]></category><category><![CDATA[middleware]]></category><category><![CDATA[abstraction]]></category><category><![CDATA[abstractions]]></category><category><![CDATA[di]]></category><category><![CDATA[dependencyinjection]]></category><category><![CDATA[dependency]]></category><category><![CDATA[injection]]></category><category><![CDATA[options]]></category><category><![CDATA[toptions]]></category><category><![CDATA[option]]></category><category><![CDATA[toption]]></category><category><![CDATA[ioption]]></category><category><![CDATA[interface]]></category><dc:creator><![CDATA[Michael Mortensen]]></dc:creator><pubDate>Sun, 30 Sep 2018 22:41:04 GMT</pubDate><media:content url="https://www.cuemon.net/blog/content/images/2018/09/000648-0001-000827.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://www.cuemon.net/blog/content/images/2018/09/000648-0001-000827.jpg" alt="ASP.NET Core: Middleware by Abstraction"><p>With ASP.NET Core the primary way of creating middleware components is by using <strong>convention-based</strong> activation logic. A secondary way is to use factory-based implementation that was added with two interfaces, <code>IMiddlewareFactory</code> and <code>IMiddleware</code>.</p>
<p>An example of convention-based middleware class looks like this:</p>
<pre style="font-family:Consolas;font-size:13px;color:gainsboro;background:#1e1e1e;"><span style="color:#57a64a;">//&#xA0;You&#xA0;may&#xA0;need&#xA0;to&#xA0;install&#xA0;the&#xA0;Microsoft.AspNetCore.Http.Abstractions&#xA0;package&#xA0;into&#xA0;your&#xA0;project</span>
<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">class</span>&#xA0;<span style="color:#4ec9b0;">ConventionalMiddleware</span>
{
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">private</span>&#xA0;<span style="color:#569cd6;">readonly</span>&#xA0;<span style="color:#4ec9b0;">RequestDelegate</span>&#xA0;_next;
 
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;ConventionalMiddleware(<span style="color:#4ec9b0;">RequestDelegate</span>&#xA0;next)
&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;_next&#xA0;<span style="color:#b4b4b4;">=</span>&#xA0;next;
&#xA0;&#xA0;&#xA0;&#xA0;}
 
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#4ec9b0;">Task</span>&#xA0;Invoke(<span style="color:#4ec9b0;">HttpContext</span>&#xA0;httpContext)
&#xA0;&#xA0;&#xA0;&#xA0;{
 
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">return</span>&#xA0;_next(httpContext);
&#xA0;&#xA0;&#xA0;&#xA0;}
}
</pre>
<p>And the factory-based implementation could look like this:</p>
<pre style="font-family:Consolas;font-size:13px;color:gainsboro;background:#1e1e1e;"><span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">class</span>&#xA0;<span style="color:#4ec9b0;">FactoryActivatedMiddleware</span>&#xA0;:&#xA0;<span style="color:#b8d7a3;">IMiddleware</span>
{
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#4ec9b0;">Task</span>&#xA0;InvokeAsync(<span style="color:#4ec9b0;">HttpContext</span>&#xA0;context,&#xA0;<span style="color:#4ec9b0;">RequestDelegate</span>&#xA0;next)
&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">throw</span>&#xA0;<span style="color:#569cd6;">new</span>&#xA0;<span style="font-weight:bold;color:#2aafd4;">NotImplementedException</span>();
&#xA0;&#xA0;&#xA0;&#xA0;}
}</pre>
<p>However, although both ways are sleak and dandy, I wanted to improve the <strong>convention-based</strong> activation with two main abstractions; one for middleware components that does not need configuration - and one that requires additional setup.</p>
<h1 id="middlewarewithzerotofivedependencyinjectedparameters">Middleware with zero to five dependency injected parameters</h1>
<p>For the first middleware abstraction, I decided to create an abstract class named <a href="https://gimlichael.github.io/api/aspnetcore/Cuemon.AspNetCore.Middleware.html"><code>Middleware</code></a>  and five additional implementations. The difference lies in the generic type parameters covering dependency injection.</p>
<p>Following our examples from before, we are ending up with a class like this:</p>
<pre style="font-family:Consolas;font-size:13px;color:gainsboro;background:#1e1e1e;"><span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">class</span>&#xA0;<span style="color:#4ec9b0;">ConventionalMiddleware</span>&#xA0;:&#xA0;<span style="color:#4ec9b0;">Middleware</span>
{
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;ConventionalMiddleware(<span style="color:#4ec9b0;">RequestDelegate</span>&#xA0;next)&#xA0;:&#xA0;<span style="color:#569cd6;">base</span>(next)
&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;}
 
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">override</span>&#xA0;<span style="color:#4ec9b0;">Task</span>&#xA0;InvokeAsync(<span style="color:#4ec9b0;">HttpContext</span>&#xA0;context)
&#xA0;&#xA0;&#xA0;&#xA0;{
 
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">return</span>&#xA0;Next(context);
&#xA0;&#xA0;&#xA0;&#xA0;}
}</pre>
<p>And if we we have one dependency on <code>ITest</code>, it could look like this:</p>
<pre style="font-family:Consolas;font-size:13px;color:gainsboro;background:#1e1e1e;"><span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">class</span>&#xA0;<span style="color:#4ec9b0;">ConventionalMiddleware</span>&#xA0;:&#xA0;<span style="color:#4ec9b0;">Middleware</span>&lt;<span style="color:#b8d7a3;">ITest</span>&gt;
{
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;ConventionalMiddleware(<span style="color:#4ec9b0;">RequestDelegate</span>&#xA0;next)&#xA0;:&#xA0;<span style="color:#569cd6;">base</span>(next)
&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;}
 
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">override</span>&#xA0;<span style="color:#4ec9b0;">Task</span>&#xA0;InvokeAsync(<span style="color:#4ec9b0;">HttpContext</span>&#xA0;context,&#xA0;<span style="color:#b8d7a3;">ITest</span>&#xA0;test)
&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">return</span>&#xA0;Next(context);
&#xA0;&#xA0;&#xA0;&#xA0;}
}</pre>
<h1 id="configurablemiddlewarewithzerotofivedependencyinjectedparameters">ConfigurableMiddleware with zero to five dependency injected parameters</h1>
<p>For the second - and probably the most relevant middleware abstraction - I went for an abstract class named <a href="https://gimlichael.github.io/api/aspnetcore/Cuemon.AspNetCore.ConfigurableMiddleware-1.html"><code>ConfigurableMiddleware</code></a> that without dependency injection has one generic type parameter, <code>TOptions</code>.</p>
<p>The constructor defer a little from the first implementation; not only does it support <code>TOptions</code>, it also comes in two flavors: one that is supported by interface <code>IOptions&lt;TOptions&gt;</code> and one that is supported by delegate <code>Action&lt;TOptions&gt;</code>.</p>
<p>When creating the recommended extension method for <code>IApplicationBuilder</code>, do consider using the static <code>ApplicationBuilderFactory</code> class to insure correct invokation of either constructor.</p>
<p>To make the usage of this middleware implementation more clear, I have included a working example that is found in the <code>Cuemon.AspNetCore</code> assembly; it is the <code>HostingEnvironmentMiddleware</code> class:</p>
<pre style="font-family:Consolas;font-size:13px;color:gainsboro;background:#1e1e1e;"><span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">summary</span><span style="color:#608b4e;">&gt;</span>
<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;Provides&#xA0;a&#xA0;hosting&#xA0;environment&#xA0;middleware&#xA0;implementation&#xA0;for&#xA0;ASP.NET&#xA0;Core.</span>
<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">summary</span><span style="color:#608b4e;">&gt;</span>
<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">class</span>&#xA0;<span style="color:#4ec9b0;">HostingEnvironmentMiddleware</span>&#xA0;:&#xA0;<span style="color:#4ec9b0;">ConfigurableMiddleware</span>&lt;<span style="color:#b8d7a3;">IHostingEnvironment</span>,&#xA0;<span style="color:#4ec9b0;">HostingEnvironmentOptions</span>&gt;
{
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">summary</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;Initializes&#xA0;a&#xA0;new&#xA0;instance&#xA0;of&#xA0;the&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">see</span><span style="color:#c8c8c8;">&#xA0;cref</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#4ec9b0;">HostingEnvironmentMiddleware</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">/&gt;</span><span style="color:#608b4e;">&#xA0;class.</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">summary</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">param</span><span style="color:#c8c8c8;">&#xA0;name</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span>next<span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">&gt;</span><span style="color:#608b4e;">The&#xA0;delegate&#xA0;of&#xA0;the&#xA0;request&#xA0;pipeline&#xA0;to&#xA0;invoke.</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">param</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">param</span><span style="color:#c8c8c8;">&#xA0;name</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span>setup<span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">&gt;</span><span style="color:#608b4e;">The&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">see</span><span style="color:#c8c8c8;">&#xA0;cref</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#4ec9b0;">HostingEnvironmentOptions</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">&#xA0;/&gt;</span><span style="color:#608b4e;">&#xA0;which&#xA0;need&#xA0;to&#xA0;be&#xA0;configured.</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">param</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;HostingEnvironmentMiddleware(<span style="color:#4ec9b0;">RequestDelegate</span>&#xA0;next,&#xA0;<span style="color:#b8d7a3;">IOptions</span>&lt;<span style="color:#4ec9b0;">HostingEnvironmentOptions</span>&gt;&#xA0;setup)&#xA0;:&#xA0;<span style="color:#569cd6;">base</span>(next,&#xA0;setup)
&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;}
 
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">summary</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;Initializes&#xA0;a&#xA0;new&#xA0;instance&#xA0;of&#xA0;the&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">see</span><span style="color:#c8c8c8;">&#xA0;cref</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#4ec9b0;">HostingEnvironmentMiddleware</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">/&gt;</span><span style="color:#608b4e;">&#xA0;class.</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">summary</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">param</span><span style="color:#c8c8c8;">&#xA0;name</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span>next<span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">&gt;</span><span style="color:#608b4e;">The&#xA0;delegate&#xA0;of&#xA0;the&#xA0;request&#xA0;pipeline&#xA0;to&#xA0;invoke.</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">param</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">param</span><span style="color:#c8c8c8;">&#xA0;name</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span>setup<span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">&gt;</span><span style="color:#608b4e;">The&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">see</span><span style="color:#c8c8c8;">&#xA0;cref</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#4ec9b0;">HostingEnvironmentOptions</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">&#xA0;/&gt;</span><span style="color:#608b4e;">&#xA0;which&#xA0;need&#xA0;to&#xA0;be&#xA0;configured.</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">param</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;HostingEnvironmentMiddleware(<span style="color:#4ec9b0;">RequestDelegate</span>&#xA0;next,&#xA0;<span style="color:#4ec9b0;">Action</span>&lt;<span style="color:#4ec9b0;">HostingEnvironmentOptions</span>&gt;&#xA0;setup)&#xA0;:&#xA0;<span style="color:#569cd6;">base</span>(next,&#xA0;setup)
&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;}
 
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">summary</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;Executes&#xA0;the&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">see</span><span style="color:#c8c8c8;">&#xA0;cref</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#4ec9b0;">HostingEnvironmentMiddleware</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">&#xA0;/&gt;</span><span style="color:#608b4e;">.</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">summary</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">param</span><span style="color:#c8c8c8;">&#xA0;name</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span>context<span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">&gt;</span><span style="color:#608b4e;">The&#xA0;context&#xA0;of&#xA0;the&#xA0;current&#xA0;request.</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">param</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">param</span><span style="color:#c8c8c8;">&#xA0;name</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span>he<span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">&gt;</span><span style="color:#608b4e;">The&#xA0;dependency&#xA0;injected&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">see</span><span style="color:#c8c8c8;">&#xA0;cref</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#b8d7a3;">IHostingEnvironment</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">/&gt;</span><span style="color:#608b4e;">&#xA0;of&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">see</span><span style="color:#c8c8c8;">&#xA0;cref</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span>InvokeAsync<span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">/&gt;</span><span style="color:#608b4e;">.</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">param</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">returns</span><span style="color:#608b4e;">&gt;</span><span style="color:#608b4e;">A&#xA0;task&#xA0;that&#xA0;represents&#xA0;the&#xA0;execution&#xA0;of&#xA0;this&#xA0;middleware.</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">returns</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">override</span>&#xA0;<span style="color:#4ec9b0;">Task</span>&#xA0;InvokeAsync(<span style="color:#4ec9b0;">HttpContext</span>&#xA0;context,&#xA0;<span style="color:#b8d7a3;">IHostingEnvironment</span>&#xA0;he)
&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;context<span style="color:#b4b4b4;">.</span>Response<span style="color:#b4b4b4;">.</span>OnStarting(()&#xA0;<span style="color:#b4b4b4;">=&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">if</span>&#xA0;(<span style="color:#b4b4b4;">!</span>Options<span style="color:#b4b4b4;">?.</span>SuppressHeaderPredicate(he)&#xA0;<span style="color:#b4b4b4;">??</span>&#xA0;<span style="color:#569cd6;">false</span>)
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;context<span style="color:#b4b4b4;">.</span>Response<span style="color:#b4b4b4;">.</span>Headers<span style="color:#b4b4b4;">.</span>AddIfNotContainsKey(Options<span style="color:#b4b4b4;">.</span>HeaderName,&#xA0;he<span style="color:#b4b4b4;">.</span>EnvironmentName);
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;}
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">return</span>&#xA0;<span style="color:#4ec9b0;">Task</span><span style="color:#b4b4b4;">.</span>CompletedTask;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;});
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">return</span>&#xA0;Next(context);
&#xA0;&#xA0;&#xA0;&#xA0;}
}
 
<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">summary</span><span style="color:#608b4e;">&gt;</span>
<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;This&#xA0;is&#xA0;a&#xA0;factory&#xA0;implementation&#xA0;of&#xA0;the&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">see</span><span style="color:#c8c8c8;">&#xA0;cref</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#4ec9b0;">HostingEnvironmentMiddleware</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">/&gt;</span><span style="color:#608b4e;">&#xA0;class.</span>
<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">summary</span><span style="color:#608b4e;">&gt;</span>
<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">static</span>&#xA0;<span style="color:#569cd6;">class</span>&#xA0;<span style="color:#4ec9b0;">HostingEnvironmentBuilderExtension</span>
{
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">summary</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;Adds&#xA0;a&#xA0;hosting&#xA0;environment&#xA0;HTTP&#xA0;header&#xA0;to&#xA0;the&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">see</span><span style="color:#c8c8c8;">&#xA0;cref</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#b8d7a3;">IApplicationBuilder</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">/&gt;</span><span style="color:#608b4e;">&#xA0;request&#xA0;execution&#xA0;pipeline.</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">summary</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">param</span><span style="color:#c8c8c8;">&#xA0;name</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span>builder<span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">&gt;</span><span style="color:#608b4e;">The&#xA0;type&#xA0;that&#xA0;provides&#xA0;the&#xA0;mechanisms&#xA0;to&#xA0;configure&#xA0;an&#xA0;application&#x2019;s&#xA0;request&#xA0;pipeline.</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">param</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">param</span><span style="color:#c8c8c8;">&#xA0;name</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span>setup<span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">&gt;</span><span style="color:#608b4e;">The&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">see</span><span style="color:#c8c8c8;">&#xA0;cref</span><span style="color:#608b4e;">=</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#4ec9b0;">CorrelationIdentifierOptions</span><span style="color:#c8c8c8;">&quot;</span><span style="color:#608b4e;">/&gt;</span><span style="color:#608b4e;">&#xA0;middleware&#xA0;which&#xA0;need&#xA0;to&#xA0;be&#xA0;configured.</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">param</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#608b4e;">///</span><span style="color:#608b4e;">&#xA0;</span><span style="color:#608b4e;">&lt;</span><span style="color:#608b4e;">returns</span><span style="color:#608b4e;">&gt;</span><span style="color:#608b4e;">A&#xA0;reference&#xA0;to&#xA0;this&#xA0;instance&#xA0;after&#xA0;the&#xA0;operation&#xA0;has&#xA0;completed.</span><span style="color:#608b4e;">&lt;/</span><span style="color:#608b4e;">returns</span><span style="color:#608b4e;">&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">static</span>&#xA0;<span style="color:#b8d7a3;">IApplicationBuilder</span>&#xA0;UseHostingEnvironmentHeader(<span style="color:#569cd6;">this</span>&#xA0;<span style="color:#b8d7a3;">IApplicationBuilder</span>&#xA0;builder,&#xA0;<span style="color:#4ec9b0;">Action</span>&lt;<span style="color:#4ec9b0;">HostingEnvironmentOptions</span>&gt;&#xA0;setup&#xA0;<span style="color:#b4b4b4;">=</span>&#xA0;<span style="color:#569cd6;">null</span>)
&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">return</span>&#xA0;<span style="color:#4ec9b0;">ApplicationBuilderFactory</span><span style="color:#b4b4b4;">.</span>UseMiddlewareConfigurable&lt;<span style="color:#4ec9b0;">HostingEnvironmentMiddleware</span>,&#xA0;<span style="color:#4ec9b0;">HostingEnvironmentOptions</span>&gt;(builder,&#xA0;setup);
&#xA0;&#xA0;&#xA0;&#xA0;}
}</pre>
<p>As you can see, this implementation has two generic type parameters; the first is for dependency injection (in this case, we depend on an implementation of <code>IHostingEnvironment</code>) and the other is the required setup of <code>HostingEnvironmentOptions</code>.</p>
<p>The rest of the code should be rather self-explanatory, but do take note of the extension method associated with this middleware.</p>
<h2 id="closingwords">Closing Words</h2>
<p>This was some insights to Middleware and ConfigurableMiddleware. I hope it brought something new for you to enjoy and triggered your curiosity to try it out in your projects.</p>
<p>Code with passion &#x1F525;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Simple ASP.NET Core MVC Razor Setup]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>With this  article I will show how this website, www.cuemon.net, has been configured in ASP.NET Core MVC 2.1.<br>
I will go through it, line by line, where there is a reference to Cuemon related code.</p>
<p>This is the <code>Startup.cs</code> file in my project which is</p>]]></description><link>https://www.cuemon.net/blog/simple-asp-net-core-mvc-razor-setup/</link><guid isPermaLink="false">60883e03c883260001fb8ff0</guid><category><![CDATA[dotnet]]></category><category><![CDATA[dotnetcore]]></category><category><![CDATA[dotnetstandard]]></category><category><![CDATA[csharp]]></category><category><![CDATA[dependencyinjection]]></category><category><![CDATA[dependency]]></category><category><![CDATA[injection]]></category><category><![CDATA[ioption]]></category><category><![CDATA[interface]]></category><category><![CDATA[toption]]></category><category><![CDATA[option]]></category><category><![CDATA[toptions]]></category><category><![CDATA[options]]></category><category><![CDATA[di]]></category><category><![CDATA[abstractions]]></category><category><![CDATA[aspnetcore]]></category><category><![CDATA[middleware]]></category><category><![CDATA[startup]]></category><dc:creator><![CDATA[Michael Mortensen]]></dc:creator><pubDate>Sat, 29 Sep 2018 12:36:21 GMT</pubDate><media:content url="https://www.cuemon.net/blog/content/images/2018/09/000222-0005-003293.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://www.cuemon.net/blog/content/images/2018/09/000222-0005-003293.jpg" alt="Simple ASP.NET Core MVC Razor Setup"><p>With this  article I will show how this website, www.cuemon.net, has been configured in ASP.NET Core MVC 2.1.<br>
I will go through it, line by line, where there is a reference to Cuemon related code.</p>
<p>This is the <code>Startup.cs</code> file in my project which is invoked by convention by ASP.NET Core.</p>
<p>
<pre style="font-family:Consolas;font-size:13px;color:gainsboro;background:#1e1e1e;"><span style="color:#569cd6;">using</span>&#xA0;Cuemon<span style="color:#b4b4b4;">.</span>AspNetCore;
<span style="color:#569cd6;">using</span>&#xA0;Cuemon<span style="color:#b4b4b4;">.</span>AspNetCore<span style="color:#b4b4b4;">.</span>Mvc<span style="color:#b4b4b4;">.</span>DependencyInjection;
<span style="color:#569cd6;">using</span>&#xA0;Cuemon<span style="color:#b4b4b4;">.</span>AspNetCore<span style="color:#b4b4b4;">.</span>Mvc<span style="color:#b4b4b4;">.</span>Filters<span style="color:#b4b4b4;">.</span>Cacheable;
<span style="color:#569cd6;">using</span>&#xA0;Cuemon<span style="color:#b4b4b4;">.</span>Homepage<span style="color:#b4b4b4;">.</span>Razor<span style="color:#b4b4b4;">.</span>TagHelpers;
<span style="color:#569cd6;">using</span>&#xA0;Microsoft<span style="color:#b4b4b4;">.</span>AspNetCore<span style="color:#b4b4b4;">.</span>Builder;
<span style="color:#569cd6;">using</span>&#xA0;Microsoft<span style="color:#b4b4b4;">.</span>AspNetCore<span style="color:#b4b4b4;">.</span>Mvc;
<span style="color:#569cd6;">using</span>&#xA0;Microsoft<span style="color:#b4b4b4;">.</span>Extensions<span style="color:#b4b4b4;">.</span>Configuration;
<span style="color:#569cd6;">using</span>&#xA0;Microsoft<span style="color:#b4b4b4;">.</span>Extensions<span style="color:#b4b4b4;">.</span>DependencyInjection;
<span style="color:#569cd6;">using</span>&#xA0;Microsoft<span style="color:#b4b4b4;">.</span>Extensions<span style="color:#b4b4b4;">.</span>Hosting;
<span style="color:#569cd6;">using</span>&#xA0;WBPA<span style="color:#b4b4b4;">.</span>WellKnownLocations;
 
<span style="color:#569cd6;">namespace</span>&#xA0;Cuemon<span style="color:#b4b4b4;">.</span>Homepage
{
&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">class</span>&#xA0;<span style="color:#4ec9b0;">Startup</span>
&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;Startup(<span style="color:#b8d7a3;">IConfiguration</span>&#xA0;configuration)
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;Configuration&#xA0;<span style="color:#b4b4b4;">=</span>&#xA0;configuration;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;}
 
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#b8d7a3;">IConfiguration</span>&#xA0;Configuration&#xA0;{&#xA0;<span style="color:#569cd6;">get</span>;&#xA0;}
 
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">void</span>&#xA0;ConfigureServices(<span style="color:#b8d7a3;">IServiceCollection</span>&#xA0;services)
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;services<span style="color:#b4b4b4;">.</span>AddOptions();
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;services<span style="color:#b4b4b4;">.</span>Configure&lt;<span style="color:#4ec9b0;">CdnTagHelperOptions</span>&gt;(Configuration<span style="color:#b4b4b4;">.</span>GetSection(<span style="color:#d69d85;">&quot;CdnTagHelperOptions&quot;</span>));
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;services<span style="color:#b4b4b4;">.</span>Configure&lt;<span style="color:#4ec9b0;">HttpCacheableOptions</span>&gt;(o&#xA0;<span style="color:#b4b4b4;">=&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;o<span style="color:#b4b4b4;">.</span>Filters<span style="color:#b4b4b4;">.</span>AddEntityTagHeader(etho&#xA0;<span style="color:#b4b4b4;">=&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;etho<span style="color:#b4b4b4;">.</span>UseEntityTagResponseParser&#xA0;<span style="color:#b4b4b4;">=</span>&#xA0;<span style="color:#569cd6;">true</span>;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;});
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;});
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;services<span style="color:#b4b4b4;">.</span>AddCacheBusting();
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;services<span style="color:#b4b4b4;">.</span>AddMvc(o&#xA0;<span style="color:#b4b4b4;">=&gt;</span>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;o<span style="color:#b4b4b4;">.</span>Filters<span style="color:#b4b4b4;">.</span>Add&lt;<span style="color:#4ec9b0;">HttpCacheableFilter</span>&gt;();
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;})<span style="color:#b4b4b4;">.</span>SetCompatibilityVersion(<span style="color:#b8d7a3;">CompatibilityVersion</span><span style="color:#b4b4b4;">.</span>Latest);
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;}
 
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span style="color:#569cd6;">public</span>&#xA0;<span style="color:#569cd6;">void</span>&#xA0;Configure(<span style="color:#b8d7a3;">IApplicationBuilder</span>&#xA0;app,&#xA0;<span style="color:#b8d7a3;">IHostingEnvironment</span>&#xA0;env)
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;{
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;app<span style="color:#b4b4b4;">.</span>UseHttpsRedirection();
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;app<span style="color:#b4b4b4;">.</span>UseStaticFiles();
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;app<span style="color:#b4b4b4;">.</span>UseHostingEnvironmentHeader();
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;app<span style="color:#b4b4b4;">.</span>UseCorrelationIdentifierHeader();
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;app<span style="color:#b4b4b4;">.</span>UseWellKnownLocations();
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;app<span style="color:#b4b4b4;">.</span>UseMvc();
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;}
&#xA0;&#xA0;&#xA0;&#xA0;}
}</pre>
</p><p>
</p><h1 id="breakdownofconfigureservicesiservicecollection">Breakdown of ConfigureServices(IServiceCollection)</h1>
<p>The first thing we do is configuring our services. Personally, I am a big fan of the Options Pattern (either by interface <code>IOptions&lt;TOptions&gt;</code> or delegate <code>Action&lt;TOptions&gt;</code>), and in this configuration, we are using the former way.</p>
<p>
<pre><code class="language-csharp">services.Configure&lt;CdnTagHelperOptions&gt;(Configuration.GetSection(&quot;CdnTagHelperOptions&quot;));
</code></pre>
</p><p>
</p><p>What happens here is actually new functionality that will be released in a near future.<br>
We are adding the options necessary for our production environment, that will be injected to or Razor views.</p>
<p>This is what the configuration looks like in <code>appsettings.Production.json</code>:</p>
<p>
<pre><code class="language-json">{
  &quot;CdnTagHelperOptions&quot;: {
    &quot;Scheme&quot;: &quot;Relative&quot;,
    &quot;BaseUrl&quot;: &quot;nblcdn.net&quot;
  }
}
</code></pre>
</p><p>
</p><p>And this is what the <code>_ViewImports.cshtml</code> looks like:</p>
<p>
<pre><code class="language-aspx-csharp">@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, cuemon.net
</code></pre>
</p><p>
</p><p>On the next line, we are adding the options for <code>HTTP ETag Header</code> which will be injected to <code>HttpCacheableFilter</code>.<br>
We are allowing dynamic parsing of the body.</p>
<p>
<pre><code class="language-csharp">services.Configure&lt;HttpCacheableOptions&gt;(o =&gt;
{
    o.Filters.AddEntityTagHeader(etho =&gt;
    {
        etho.UseEntityTagResponseParser = true;
    });
});
</code></pre>
</p><p>
</p><p>On the next line, we are adding <code>AssemblyCacheBusting</code> capabilities using the default shorthand. It basicly juts add a thumbprint to the earlier mentioned <code>Cdn*TagHelpers</code>. from the running assembly of the application. Since stylesheets changes rather often, we could consider using a <code>DynamicCacheBusting</code> instead.</p>
<p>
<pre><code class="language-csharp">services.AddCacheBusting();
</code></pre>
</p><p>
</p><p>On the last line, we are doing the actual configuration of MVC to use the earlier mentioned <code>HttpCacheableFilter</code>.</p>
<p>
<pre><code class="language-csharp">services.AddMvc(o =&gt;
{
    o.Filters.Add&lt;HttpCacheableFilter&gt;();
}).SetCompatibilityVersion(CompatibilityVersion.Latest);
</code></pre>
</p><p>
</p><p>
</p><h1 id="breakdownofconfigureiapplicationbuilderihostingenvironment">Breakdown of Configure(IApplicationBuilder, IHostingEnvironment)</h1>
<p>Lastly, we are configuring our application to make use of some the features that are not strongly necessary, but can help in your everyday development with ASP.NET Core MVC.</p>
<p>First we add a HTTP header to the response, that reveals the current environment. Default header name is <code>X-Hosting-Environment</code>.</p>
<p>
<pre><code class="language-csharp">app.UseHostingEnvironmentHeader();
</code></pre>
</p><p>
</p><p>Next, and this is because if work with SOA in my daily work, we add a Correlation-ID to the response. Default header name is <code>X-Correlation-ID</code>.</p>
<pre><code class="language-csharp">app.UseCorrelationIdentifierHeader();
</code></pre>
<p>
</p><p>Lastly, and this is a sister project to Cuemon, we configure the application to use RFC 5785 that defines a path to <code>/.well-known/</code>. We do this as the website is using LetsEncrypt SSL.</p>
<p>
<pre><code class="language-csharp">app.UseWellKnownLocations();
</code></pre>
</p><p>
</p><p>
</p><h2 id="closingwords">Closing Words</h2>
<p>This was a walkthrough of the somewhat simple setup of this website. I hope it brought something new for you to enjoy.</p>
<p>Code with passion &#x1F525;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Blog 2.0 - or at least the engine behind]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>As you have probably noticed by now - all is new!</p>
<p>The homepage is new - the blog is new. In fact, the blog is so new, that it was impossible to import the old content to this new version.</p>
<p>Long story short; i went from Ghost 0.11 --&</p>]]></description><link>https://www.cuemon.net/blog/blog-2-0-or-whatever/</link><guid isPermaLink="false">60883e03c883260001fb8fef</guid><dc:creator><![CDATA[Michael Mortensen]]></dc:creator><pubDate>Sat, 29 Sep 2018 03:18:58 GMT</pubDate><media:content url="https://www.cuemon.net/blog/content/images/2018/09/Cuemon-Cover-Facebook.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://www.cuemon.net/blog/content/images/2018/09/Cuemon-Cover-Facebook.png" alt="Blog 2.0 - or at least the engine behind"><p>As you have probably noticed by now - all is new!</p>
<p>The homepage is new - the blog is new. In fact, the blog is so new, that it was impossible to import the old content to this new version.</p>
<p>Long story short; i went from Ghost 0.11 --&gt; 2.1.4, and the changes has been many.</p>
<p>Fear not .. I will make it my goal to keep this blog alive with new and exiting content.</p>
<p>For now, this is just a placeholder to see that the blog engine is working - and that content is coming .. just like winter ;-)</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>