<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>C# / .Net &#8211; XtremeOwnage</title>
	<atom:link href="https://xtremeownage.com/category/technology/software-development/c-net/feed/" rel="self" type="application/rss+xml" />
	<link>https://xtremeownage.com</link>
	<description>Cars, Computers, and Code.</description>
	<lastBuildDate>Sun, 08 Jan 2023 02:09:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.4.3</generator>

<image>
	<url>https://xtremeownage.com/wp-content/uploads/2019/09/cropped-Turbo-512-2-100x100.png</url>
	<title>C# / .Net &#8211; XtremeOwnage</title>
	<link>https://xtremeownage.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>C# &#8211; Dynamically Invoking Method on RuntimeTypes</title>
		<link>https://xtremeownage.com/2019/12/20/c-dynamically-invoking-method-on-runtimetypes/</link>
		
		<dc:creator><![CDATA[XO]]></dc:creator>
		<pubDate>Fri, 20 Dec 2019 21:35:53 +0000</pubDate>
				<category><![CDATA[C# / .Net]]></category>
		<guid isPermaLink="false">https://xtremeownage.com/?p=787</guid>

					<description><![CDATA[Dynamically invoking methods on Types resolved at runtime via Attributes.]]></description>
										<content:encoded><![CDATA[
<p>I have an interesting project I set out to create today-</p>



<p><br>I wanted to build a simple page, which would allow our NOC to trigger certain workflows, automatically (assuming they have proper permission)</p>



<p>My requirements:</p>



<ol><li>Jobs should be easily added to the list, just by specifying an Attribute, and Implementing an interface (to ensure the proper method exists)</li><li>Jobs needs to be kicked off on my back-end servers and not on the web-front end.</li><li>Everything needs to be properly logged.</li><li>The front-end needs visual-feedback a job has been executed.</li></ol>



<p></p>



<h3 class="wp-block-heading">Here is the web page to trigger jobs.</h3>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1335" height="423" src="https://i2.wp.com/xtremeownage.com/wp-content/uploads/2019/12/NOC-Automation-Page.png?fit=1024%2C324&amp;ssl=1" alt="" class="wp-image-789" srcset="https://xtremeownage.com/wp-content/uploads/2019/12/NOC-Automation-Page.png 1335w, https://xtremeownage.com/wp-content/uploads/2019/12/NOC-Automation-Page-300x95.png 300w, https://xtremeownage.com/wp-content/uploads/2019/12/NOC-Automation-Page-1024x324.png 1024w, https://xtremeownage.com/wp-content/uploads/2019/12/NOC-Automation-Page-768x243.png 768w" sizes="(max-width: 1335px) 100vw, 1335px" /></figure>



<p>As you can see, the above page is very simple.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1194" height="423" src="https://i2.wp.com/xtremeownage.com/wp-content/uploads/2019/12/Job-Triggered.png?fit=1024%2C363&amp;ssl=1" alt="" class="wp-image-790" srcset="https://xtremeownage.com/wp-content/uploads/2019/12/Job-Triggered.png 1194w, https://xtremeownage.com/wp-content/uploads/2019/12/Job-Triggered-300x106.png 300w, https://xtremeownage.com/wp-content/uploads/2019/12/Job-Triggered-1024x363.png 1024w, https://xtremeownage.com/wp-content/uploads/2019/12/Job-Triggered-768x272.png 768w" sizes="(max-width: 1194px) 100vw, 1194px" /><figcaption>When a job is successfully triggered, the button will turn green, and it will be disabled.</figcaption></figure>



<p>In the above image, if a job fails, it will turn red, with direction to call the developers (me).</p>



<h2 class="wp-block-heading">How it works (Short Version)</h2>



<p>At startup, Reflection is used to build a dictionary containing types which implement IRemoteJob interface, and the NocJob attribute. </p>



<p>A webpage displays the values. Permissions are implemented at the controller level.</p>



<p>When a job is triggered, the Type&#8217;s full name is passed back to the method. The method will compare the provided name, against the dictionary of valid workflows. If the workflow is found, and verification passes, <a href="http://hangfire.io">Hangfire.Io</a> is then used to execute the workflow on my backend- automation services away from the web front end.</p>



<p>Since- we cannot execute a string containing the name of a type&#8230; We utilize Ninject&#8217;s kernel to resolve a instance of the class. We then Invoke the execute method, which is defined by the IRemoteJob interface, on the class instance.</p>



<p>Error handling is handed by Hangfire.</p>



<p>In short- that is it.</p>



<h2 class="wp-block-heading">How it works (Long Version)</h2>



<h4 class="wp-block-heading">RuntimeTypeResolver.cs // IRunTimeTypeResolver</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    public class RuntimeTypeResolver : IRuntimeTypeResolver
    {
        private IKernel kernel;
        public RuntimeTypeResolver(IKernel Kernel)
        {
            this.kernel = Kernel;
        }
        public object GetInstanceOfType(Type type)
        {
            return kernel.Get(type);
        }
    }</pre>



<p>This class, resolves a class instance from the Ninject kernel and returns it.</p>



<h4 class="wp-block-heading">JobHelper.cs</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">//Note - Singleton class.
    public class JobHelper
    {
        //IRunTimeTypeResolver passes a Type into a dependancy injection kernel. The kernel will return a instance of the Type.
        private IRuntimeTypeResolver rtr;
        public JobHelper(IJobScheduler JOB, IRuntimeTypeResolver RTR)
        {
            this.rtr = RTR;
            //Note- Dictionary only needs to be populated at startup.

            //Create a dictionary containing all eligible classes to be executed ad-hoc.
            RemoteJobs = this.GetType() //Types are filtered to this current assembly.
                .Assembly
                .GetTypes()
                //Type/Class implements IRemoteJob interface, and is NOT an interface or abstract class.
                .Where(x => (typeof(IRemoteJob).IsAssignableFrom(x) &amp;&amp; !x.IsInterface &amp;&amp; !x.IsAbstract))
                //Class has the NocJobAttribute, which contains display information.
                .Where(x => Attribute.IsDefined(x, typeof(NocJobAttribute)))
                //Cast the types, and create a dictionary.
                .ToDictionary(o => (NocJobAttribute)Attribute.GetCustomAttribute(o, typeof(NocJobAttribute)), o => o);
        }

        //A read-only dictionary containing the information. 
        public IReadOnlyDictionary&lt;NocJobAttribute, Type> RemoteJobs { get; }

        /// &lt;summary>
        /// This is intended as an entry point for background jobs. 
        /// &lt;/summary>
        /// &lt;param name="JobName">&lt;/param>
        public void EnqueueRemoteJob(string JobName)
        {
            //Get the Type from the list.
            Type Rec = RemoteJobs
               .First(o => o.Value.FullName.Equals(JobName, StringComparison.OrdinalIgnoreCase))
               .Value;

            //Get the Execute method. It should exist, because all items in this list, implement IRemoteJob.
            MethodInfo ExecuteMethod = Rec.GetRuntimeMethod("Execute", new Type[] { });

            //Get a instance of the type, from the RuntimeTypeResolver class.
            object Instance = rtr.GetInstanceOfType(Rec);

            //Invoke the Execute Method on the class instance.
            ExecuteMethod.Invoke(Instance, null);
        }
    }</pre>



<p>The primary purpose of this job, is to both hold a list of &#8220;valid&#8221; workflows which can be executed, and to expose a method which the Hangfire.io can trigger with the Type&#8217;s name, to invoke the workflow.</p>



<h4 class="wp-block-heading">JobController.cs &#8211; Trigger_NOC_Job method</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">        [HttpPost]
        [CheckPermissionAttribute(Permission.Trigger_AutomationJobs)]
        public ActionResult Trigger_NOC_Job(string JobType)
        {
            log.Component = "Trigger";
            var L = new JobTriggerLog
            {
                JobName = new string[] { JobType },
                Time = DateTime.Now,
                UserID = User.Identity.Name,
                UserName = User.GetFullName()
            };
            try
            {
                //now the FUN part...
                if (!jobHelper.RemoteJobs.Any(o => o.Value.FullName.Equals(JobType, StringComparison.OrdinalIgnoreCase)))
                {
                    L.Error = new Exception("Job was not located.").GetUsefulDetails(false);
                    log.Error(L);
                    return new HttpStatusCodeResult(System.Net.HttpStatusCode.NotFound, "Job was not found.");
                }

                //Get the Type from the list.
                Type Rec = jobHelper
                   .RemoteJobs
                   .First(o => o.Value.FullName.Equals(JobType, StringComparison.OrdinalIgnoreCase))
                   .Value;

                //Sanity check to double-check the Execute method exists, without required parameters.
                if (Rec.GetRuntimeMethod("Execute", new Type[] { }) == null)
                    throw new NullReferenceException("Execute method was not found on job.");

                //Use IJobScheduler to enqueue the job on the backend automation services.
                job.Enqueue&lt;JobHelper>(o => o.EnqueueRemoteJob(JobType));

                log.Success(L);

                return Json(true);
            }
            catch (Exception ex)
            {
                L.Error = ex.GetUsefulDetails();
                log.Error(L);
                return new HttpStatusCodeResult(System.Net.HttpStatusCode.InternalServerError, $"Something went wrong. {ex.Message}");
            }
            finally
            {
                log.SendLogSession();
            }
        }</pre>



<p>This is the api which is called when a user would like to trigger a workflow.</p>



<h2 class="wp-block-heading">Why is this interesting?</h2>



<p>Creating a method for each action is easy to do. Creating a single method which can dynamically invoke class instances at runtime, while resolving all of their dependencies, and following your current error handling strategies- isn&#8217;t quite so easy. <br><br>This process- allows me as the developer, to quickly, and easily add new workflows / jobs to the NOC visible page. The NOC can easily trigger the jobs&#8230;. and the process of creating the class instances, resolving dependencies&#8230;. is all auto-magically handled by the dependency injection framework.</p>



<p>As well, I have not posted anything in a while, and I felt this was interesting enough to share.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>c# &#8211; Paging Urls using abstraction and generics</title>
		<link>https://xtremeownage.com/2019/10/08/c-paging-urls-using-abstraction-and-generics/</link>
		
		<dc:creator><![CDATA[XO]]></dc:creator>
		<pubDate>Tue, 08 Oct 2019 18:59:06 +0000</pubDate>
				<category><![CDATA[C# / .Net]]></category>
		<guid isPermaLink="false">https://xtremeownage.com/?p=536</guid>

					<description><![CDATA[Despite the nasty sounding title, this post will demonstrate an easy method to abstract the paging of an applications URL. For my particular use-case, I need to retrieve many records...]]></description>
										<content:encoded><![CDATA[
<p>Despite the nasty sounding title, this post will demonstrate an easy method to abstract the paging of an applications URL.</p>



<p>For my particular use-case, I need to retrieve many records from an application called <a href="https://www.rapid7.com/">Rapid7</a> for the purpose of exporting the data into Splunk. To do this successfully, I will need to query 5 or 10 separate tables, and I will need to page the results for each table.</p>



<p>I am sure many of you have written logic like this before, and included the paging logic directly in the method for each table. Myself- I am a huge fan of writing simple, clean abstracted code, which is easy to read&#8230; Since, this will be mostly the same logic, over and over&#8230; It makes sense</p>



<h4 class="wp-block-heading">Application Logic</h4>



<p>I like to have a strong separation between the &#8220;What&#8221; the workflow is doing, and &#8220;How&#8221; it is accomplished. I handle this by using copious amounts of abstraction. Here is the main logic:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">        public async Task Execute(IJobCancellationToken jobCancellationToken)
        {
            try
            {
                //var splunk = log.CreateSplunkTarget(splunk_Index, null, splunk_Source);

                int TotalAssetCount = 0;
                await foreach (var asset in PageAllResults(GetAsset, jobCancellationToken.ShutdownToken))
                {
                    TotalAssetCount++;
                }


                int total_Exceptions = 0;
                await foreach (var asset in PageAllResults(GetVulnerability_Exceptions, jobCancellationToken.ShutdownToken))
                {
                    total_Exceptions++;
                }

                //For testing- Output results to console for validation testing. 
                Console.WriteLine(TotalAssetCount);
                Console.WriteLine(total_Exceptions);
            }
            catch (OperationCanceledException)
            {
                if (jobCancellationToken.ShutdownToken.IsCancellationRequested)
                {
                    log.Warning("Workflow was cancelled.");
                    return;
                }
                throw; //Let the normal exception handler handle this.... since cancellation was not requested.
            }
            catch (Exception ex)
            {
                //Log the exception as fatal error.
                log.Fatal(ex.GetUsefulDetails());

                //Throw the exception to allow the job scheduler to handle the retry logic.
                throw;
            }
            finally
            {
                //This will invoke the logic to send out error emails to subscribers to this workflow.
                log.SendLogSession();
            }
        }</pre>



<p>For this article, it is only currently doing a count of the records returned. </p>



<p>You will notice the IJobCancellationToken. All of my &#8220;Automation Jobs&#8221; are configured with the idea in mind, that the server, or service, or job may need to be cancelled at any time. If any of those events happens to occur, The cancellationToken is passed down to allow a graceful stop of the application.</p>



<p>The logic executing this code contains the logic to automatically re-enqueue the job on another server when the previous job is cancelled.</p>



<h2 class="wp-block-heading">How to abstract paging the results of multiple method calls</h2>



<p>Next up- we will look at a method whose sole purpose, is to page the results of a method. This method is tailored specifically to this class, and prevents us from repeating the paging logic for each api(over 15 in total).</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">private async IAsyncEnumerable&lt;T> PageAllResults&lt;T>(Func&lt;int, CancellationToken, Task&lt;Wrapper&lt;T>>> action, [EnumeratorCancellation]CancellationToken ct) where T : class
        {
            bool HasMoreRecords = true;
            int Start = 0;

            do
            {
                var Results = await action.Invoke(Start, ct).ConfigureAwait(false);

                foreach (var a in Results.Resources)
                {
                    yield return a;
                }

                HasMoreRecords = Start &lt; Results.Page.TotalPages;
                Start++;
            }
            while (HasMoreRecords);
        }</pre>



<p>While the method signature may look scary- It is actually very simple to utilize. This method contains the application API-specific logic to handle paging for all of the GET requests we will be performing.</p>



<h4 class="wp-block-heading">Methods for specific APIs</h4>



<p>For the individual APIs, While I could abstract this logic into a dictionary, I decided to leave everything into its own individual method to allow me to easily document and customize the parameters per call. As well- if I need to intercept the results, and perform modification on the fly, it would allow me to easily contain the logic here. There will be around 15+ of these in total.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">        private Task&lt;Wrapper&lt;Asset>> GetAsset(int Start, CancellationToken ct)
        {
            //https://help.rapid7.com/insightvm/en-us/api/index.html#operation/getAssets
            var uri = new UriBuilder("https", baseUri, 443, "/api/3/assets");
            uri.Query = $"page={Start}&amp;size={50}&amp;sort=idASC";

            return QueryRapid7_GET&lt;Asset>(uri.Uri, ct);
        }

        private Task&lt;Wrapper&lt;Vulnerability_Exception>> GetVulnerability_Exceptions(int Start, CancellationToken ct)
        {
            //https://help.rapid7.com/insightvm/en-us/api/index.html#operation/getVulnerabilityExceptions
            var uri = new UriBuilder("https", baseUri, 443, "/api/3/assets");
            uri.Query = $"page={Start}&amp;size={500}&amp;sort=idASC";

            return QueryRapid7_GET&lt;Vulnerability_Exception>(uri.Uri, ct);
        }</pre>



<p>You will notice- The entire purpose of this method, is focused specifically how to obtain the results for the provided API. It does not contain the paging logic, or even the logic on how to perform the GET request. This allows for less code-duplication overall, which leads to a simpler product.</p>



<p>Lastly- In the current implementation of these two tables, it does not use Async. Rather, it passes the Task back to the calling method, without waiting for it to complete.</p>



<h2 class="wp-block-heading">Lastly- Abstractions for performing the request.</h2>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">        private async Task&lt;Wrapper&lt;T>> QueryRapid7_GET&lt;T>(Uri Uri, CancellationToken ct) where T : class
        {
            string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(creds.UserName + ":" + creds.Password));

            var obj = await rest.GetObjectAsync&lt;Wrapper&lt;T>>(Uri, HttpMethod.Get, ct, RequestBody: null, Configure: o =>
           {
               o.Headers[HttpRequestHeader.Authorization] = $"Basic {credentials}";
           }).ConfigureAwait(false);


            if (obj.Exception != null)
                throw obj.Exception;

            return obj.Object;
        }</pre>



<p>The purpose of this method, is similarly to perform a GET query against the rapid7 API. To perform the query, it only needs to know the Uri, and the credentials (which are set by the constructor.).</p>



<p>Again- there is no logic for creating the URI specific to the endpoint, There is no logic for paging. The only logic contained in the method, is to perform a GET query against the provided URI.</p>



<p>Both error handling and CancellationTokens are built into my RestHelper class. This allows graceful cancellation of the workflows, as well as- allowing me to seperate my logic, from my error handling.</p>



<h2 class="wp-block-heading">Why Would I do that? That looks complicated!</h2>



<p>Because when this workflow is expanded to perform logic on each of the hundred+ APIs offered- The code will remain very readable with minimal repeated logic.</p>



<p>Each method is very specific to its own purpose, with as little overlap as possible. The end result, will be cleaner code, with less wasted room.</p>



<p>Now- if you job rates you based on lines of code written, by all means- Don&#8217;t abstract at all. Copy and paste everything!</p>



<p>However- if you like building supportable software, Separating areas of functionality will allow you to build a much more supportable product. As well, it is much easier to write a unit test for your methods, when they are responsible for performing a single task.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
