<?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>ASP.NET Archives | DMC, Inc.</title>
	<atom:link href="https://static.dmcinfo.com/blog/tag/asp-net/feed/index.xml" rel="self" type="application/rss+xml" />
	<link></link>
	<description></description>
	<lastBuildDate>Fri, 24 Jul 2026 19:09:02 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>

<image>
	<url>https://static.dmcinfo.com/wp-content/uploads/2025/04/site-icon-150x150.png</url>
	<title>ASP.NET Archives | DMC, Inc.</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>6 Easy Steps to Get Started with MVC Module Development in DNN 8</title>
		<link>https://static.dmcinfo.com/blog/25071/6-easy-steps-to-get-started-with-mvc-module-development-in-dnn-8/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Fri, 14 Oct 2016 12:37:43 +0000</pubDate>
				<category><![CDATA[Web Application Development]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C# .NET Application Development]]></category>
		<category><![CDATA[Dot Net Nuke]]></category>
		<category><![CDATA[HTML and CSS]]></category>
		<category><![CDATA[MS Visual Studio/.NET]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/25071/6-easy-steps-to-get-started-with-mvc-module-development-in-dnn-8/</guid>

					<description><![CDATA[<p>In the beginning of the year,&#160;DNN (formerly DotNetNuke) was updated to support MVC modules. MVC is the latest version of ASP.NET in which the Model-View-Controller paradigm is at the core.&#160;This article won&#8217;t be a look into what MVC is or a comparison with WebForms, but instead will give a quick guide into starting DNN MVC [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/25071/6-easy-steps-to-get-started-with-mvc-module-development-in-dnn-8/">6 Easy Steps to Get Started with MVC Module Development in DNN 8</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In the beginning of the year,&nbsp;DNN (formerly DotNetNuke) was updated to support MVC modules. MVC is the latest version of ASP.NET in which the Model-View-Controller paradigm is at the core.&nbsp;This article won&#8217;t be a look into what MVC is or a comparison with WebForms, but instead will give a quick guide into starting DNN MVC module development.</p>



<p class="wp-block-paragraph">While there are some guides available that give you similar information, I found it a bit difficult to get started developing MVC modules in DNN. For reference, the articles I used are at the bottom of this blog.</p>



<p class="wp-block-paragraph">Here&#8217;s an overview of the steps we&#8217;ll take to get started.</p>



<ol class="wp-block-list">
<li><a href="#prerequisites">Prerequisites</a></li>



<li><a href="#templates">Templates</a></li>



<li><a href="#setup">Setup</a></li>



<li><a href="#build">Build</a></li>



<li><a href="#installation">Installation</a></li>



<li><a href="#next-steps">Next Steps</a></li>



<li><a href="#references">References</a></li>
</ol>



<h2 id="prerequisites" class="wp-block-heading">1. Prerequisites</h2>



<p class="wp-block-paragraph">For this quick start, you&#8217;ll need a few things before we can dive in.</p>



<p class="wp-block-paragraph">First, you&#8217;ll need to have Visual Studio 2015 installed. The express editions have been reported to be incompatible with the templates we&#8217;ll be using later, but this may not be true by the time you&#8217;re reading this.</p>



<p class="wp-block-paragraph">Next, you&#8217;ll need to have IIS (Internet Information Services) setup with a local installation of DNN (version 8 or higher). There are many tutorials on how to do this around the web. You&#8217;ll need to install IIS and&nbsp;Microsoft SQL Server, then you can install DNN by downloading the latest _install.zip from <a href="https://github.com/dnnsoftware/Dnn.Platform/releases" target="_blank">DNN&#8217;s GitHub releases</a>.</p>



<p class="wp-block-paragraph">Once those are all set up, you&#8217;re ready to go.</p>



<h2 id="templates" class="wp-block-heading">2. Templates</h2>



<p class="wp-block-paragraph">You <em>could&nbsp;</em>create a module from scratch. But why would you do that when a DNN expert created templates for you to use? <a href="https://marketplace.visualstudio.com/items?itemName=Chris-Hammond.DotNetNukeDNNDevelopmentProjectTemplates" target="_blank" rel="noreferrer noopener">Download the templates from the Visual Studio Gallery</a>&nbsp;and run through the installation procedure.</p>



<h2 id="setup" class="wp-block-heading">3. Setup</h2>



<p class="wp-block-paragraph">Now that everything is set up, we can actually dive into creating the module.&nbsp;</p>



<p class="wp-block-paragraph">In Visual Studio, select File -&gt; New -&gt; Project</p>



<p class="wp-block-paragraph">In the New Project window, select Templates -&gt; Visual C# -&gt; DotNetNuke and you&#8217;ll see a listing of the types of projects the templates have provided.</p>



<p class="wp-block-paragraph">To create an MVC module, we&#8217;ll select DotNetNuke 8 C# DAL2 MVC Module. There are three other fields we must configure: Name, Location, and Solution name.</p>



<p class="wp-block-paragraph"><strong>Name: </strong>Enter a name for your project (it&#8217;s best not to use any spaces or special characters for this)</p>



<p class="wp-block-paragraph"><strong>Location:&nbsp;</strong>This is important to point this to the correct folder in DNN: /DesktopModules/MVC/.&nbsp;Depending on your installation directory, the folder should be something like C:\Dev\Projects\DMC_Website\Alpha\DesktopModules\MVC\ where &#8220;Alpha&#8221; is the root of your DNN installation.</p>



<p class="wp-block-paragraph"><strong>Solution name:</strong>&nbsp;We&#8217;re not actually going to be using this field. Uncheck&nbsp;the box on the right that says &#8220;Create directory for solution&#8221; and the solution name textbox will be greyed out.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/2016-10-28-12_40_42-New-Project.png" alt="Configuration of the DotNetNuke 8 C# DAL2 MVC Module Visual Studio Project"/></figure>



<p class="wp-block-paragraph">Confirm your settings look similar to mine and then click OK.</p>



<p class="wp-block-paragraph">A Project Setup Wizard dialog box will appear asking for some project information. Many of these are self explanatory, so I will only address the two that are a bit tricky.</p>



<p class="wp-block-paragraph"><strong>Namespace: </strong>Whatever namespace you want your module to live in. The templates will automatically include your project name in the namespace, so no need to enter it here.&nbsp;Make sure you include the last period. E.g. DMC.</p>



<p class="wp-block-paragraph"><strong>Local Dev URL:&nbsp;</strong>By default this is set up to point to dnndev.me, which is actually set up to point back to 127.0.0.1 (your localhost). What you enter here depends on what settings you&#8217;ve set your DNN install up with. For my installation, I access my local DNN install through http://localhost./ Therefore, I am going to enter localhost as my Local Dev URL.</p>



<p class="wp-block-paragraph">Initial values</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/2016-10-14-12_49_25-Project-Setup-Wizard.png" alt="DNN Template Setup Wizard Initial Values"/></figure>



<p class="wp-block-paragraph">Updated values (note: the owner website field includes https:// but the textbox isn&#8217;t large enough to display it. Be sure to include it in your URL.)</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/2016-10-28-12_42_14-Project-Setup-Wizard.png" alt="DNN Template Setup Wizard Updated Values"/></figure>



<p class="wp-block-paragraph">Once all fields have been complete, click OK.</p>



<h2 id="build" class="wp-block-heading">4. Build</h2>



<p class="wp-block-paragraph">Now that the initial project setup is complete, you&#8217;ll be presented with a web page in Visual Studio that says * Important *. These are steps that you should&nbsp;<strong>read carefully</strong>&nbsp;and follow to ensure your project will work correctly. I&#8217;ll provide a quick overview of these steps in case the original wording is confusing for anyone.</p>



<p class="wp-block-paragraph">First, check IIS to see if any of your folders were converted to virtual directories or applications. To do this, open IIS, expand your site&#8217;s dropdown and check what icon is displayed next to your DesktopModules folder or the MVC folder inside of the DesktopModules folder. If it&#8217;s anything other than a yellow folder, right click it and click remove.</p>



<p class="wp-block-paragraph">Next, in Visual Studio, right click and delete the web.config files that are in the solution.</p>



<p class="wp-block-paragraph">You can now build the module! change the solution configuration dropdown from Debug to Release and then select Build -&gt; Build</p>



<p class="wp-block-paragraph">You&#8217;ll get an install .zip file in your module&#8217;s install/ directory.</p>



<h2 id="installation" class="wp-block-heading">5. Installation</h2>



<p class="wp-block-paragraph">Now, in DNN, go to Hosts -&gt; Extensions and click Install Extension, selecting your install .zip file that you previously built.</p>



<p class="wp-block-paragraph">If everything goes well, then the module is now installed and can be placed on any page.</p>



<h2 id="next-steps" class="wp-block-heading">6. Next Steps</h2>



<p class="wp-block-paragraph">Once you&#8217;ve dragged the module into a page, you&#8217;ll see a demo application that includes multiple views, database interaction, and more. Simply build the project in debug mode to automatically copy the new DLL to the /bin folder.</p>



<h2 id="references" class="wp-block-heading">7. References</h2>



<ul class="wp-block-list">
<li><a href="https://www.chrishammond.com/tag/dotnetnuke" type="link" id="https://www.chrishammond.com/tag/dotnetnuke" target="_blank" rel="noreferrer noopener">Chris Hammond&#8217;s DNN posts</a></li>



<li><a href="https://dnncommunity.org/blogs" type="link" id="https://dnncommunity.org/blogs" target="_blank" rel="noreferrer noopener">DNN Community Blogs</a></li>



<li><a href="https://www.dnnsoftware.com/docs/developers/mvc-modules/mvc-module-development.html" type="link" id="https://www.dnnsoftware.com/docs/developers/mvc-modules/mvc-module-development.html" target="_blank" rel="noreferrer noopener">DNN MVC Module Development</a></li>
</ul>



<p class="wp-block-paragraph">While you&#8217;re here, check out DMC&#8217;s <a href="/services/application-development/web-application-development">Web Application Development</a> and <a href="/services/application-development/web-application-development/aspnet-and-aspnet-mvc">ASP.NET &amp; ASP.NET MVC Development</a> services so we can get started on your next DNN MVC module!</p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://static.dmcinfo.com/blog/25071/6-easy-steps-to-get-started-with-mvc-module-development-in-dnn-8/">6 Easy Steps to Get Started with MVC Module Development in DNN 8</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Querying the Active Directory</title>
		<link>https://static.dmcinfo.com/blog/25759/querying-the-active-directory/</link>
		
		<dc:creator><![CDATA[Christopher Olsen]]></dc:creator>
		<pubDate>Tue, 26 Apr 2016 13:26:52 +0000</pubDate>
				<category><![CDATA[Web Application Development]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[MS Visual Studio/.NET]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/25759/querying-the-active-directory/</guid>

					<description><![CDATA[<p>While developing a .NET application, you may find that you need to access data that is stored in the Active Directory (AD). In these cases, if you’re not experienced with querying the AD, you may be tempted to create a copy of the data you need into a SQL database – however, this would amount [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/25759/querying-the-active-directory/">Querying the Active Directory</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">While developing a .NET application, you may find that you need to access data that is stored in the Active Directory (AD). In these cases, if you’re not experienced with querying the AD, you may be tempted to create a copy of the data you need into a SQL database – however, this would amount to unnecessary data redundancy.</p>



<p class="wp-block-paragraph">Fortunately, pulling data from the AD and using it in your application is much easier than you might think, and allows you to maintain data integrity by keeping your data in just one place. Also, SharePoint developers will be happy to learn that the AD can be queried from within a SharePoint add-in with the same code that I&#8217;ll be sharing here.</p>



<p class="wp-block-paragraph">First, let’s have a brief review of what the Active Directory (AD) is:</p>



<p class="wp-block-paragraph">The AD is, for the purpose being discussed here, basically a database, except that its storage is hierarchical in nature. The data it stores typically regards the different components in a computer network. For example, a very common use of the AD is to store various pieces of information about a user (email address, name, phone number, title/job description, etc.) It may also contain data about user groups, such as the marketing department, IT, etc.</p>



<h2 id="h-getting-started" class="wp-block-heading">Getting Started</h2>



<p class="wp-block-paragraph">The first thing you’ll need to do is figure out what your AD domain path is. <span style="line-height: 1.6;">Also, if you&#8217;re querying the AD from within a SharePoint add-in, you&#8217;ll need to make sure that the user under which the Add-in web service is running has the proper permissions to access the AD.</span></p>



<p class="wp-block-paragraph">And finally, it should be said at this point that you’ll need to use a few .NET assemblies that you may have never touched before:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">C#</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>using System.DirectoryServices;

using AD = System.DirectoryServices.ActiveDirectory;
using AP = System.DirectoryServices.Protocols;
using AM = System.DirectoryServices.AccountManagement;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #C586C0">using</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">System</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">DirectoryServices</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #C586C0">using</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">AD</span><span style="color: #D4D4D4"> = </span><span style="color: #4EC9B0">System</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">DirectoryServices</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">ActiveDirectory</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #C586C0">using</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">AP</span><span style="color: #D4D4D4"> = </span><span style="color: #4EC9B0">System</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">DirectoryServices</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">Protocols</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #C586C0">using</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">AM</span><span style="color: #D4D4D4"> = </span><span style="color: #4EC9B0">System</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">DirectoryServices</span><span style="color: #D4D4D4">.</span><span style="color: #4EC9B0">AccountManagement</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<h2 id="h-example-getting-user-info" class="wp-block-heading">Example: Getting User Info</h2>



<p class="wp-block-paragraph">Something I often find myself having to do is get a list of all users in the AD, along with some piece of data associated with them. In this example, we&#8217;ll be building a Dictionary that associates each user with the name of their manager.</p>



<p class="wp-block-paragraph">First, let&#8217;s show you the code, then we&#8217;ll explain it.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/code1.png" alt="Active Directory querying code"/></figure>



<p class="wp-block-paragraph">After we’ve declared an empty dictionary, and retrieved our current path, we go ahead and create an instance of the DirectoryEntry class, passing our domain path as a parameter to its constructor. It should be noted that most of these DirectoryServices classes implement the IDisposable interface, meaning that we need to make sure we dispose of them after we’re done using them. To make this easier, of course, we utilize “using” statements here, so that our unmanaged resources automatically get released.</p>



<p class="wp-block-paragraph">Next, we pass our DirectoryEntry as a parameter to the DirectorySearcher class constructor. The DirectorySearcher class’ main purpose is to allow us to query the AD.</p>



<p class="wp-block-paragraph">Now that we have our DirectorySearcher instance, the wise thing to do is to use a filter to narrow our search results – if we skip this step, we sacrifice performance. So we assign to the DirectorySearcher’s Filter property a string that represents an LDAP query. In this case, our query “(&amp;(objectCategory=User)(objectClass=person))” returns only objects that are in the User category and that implement the “person” class.</p>



<p class="wp-block-paragraph">Now, for a given AD object, there can be dozens or even hundreds of properties. So to save on performance, we only want our query to return those properties which we’ll actually be using. To do this, we add property names as strings to the PropertiesToLoad property of our DirectorySearcher. Finally, we execute the query by calling the FindAll method of the DirectorySearcher. This returns a SearchResultCollection.</p>



<p class="wp-block-paragraph">Iterating through this collection gives us access to SearchResult class instances. To avoid a null reference exception, I like to ensure that each SearchResult actually has the properties that I’m looking for. After that, getting our values is a simple matter of accessing the Properties property of the SearchResult with a string indexer. In this case, both are properties are simply strings, so I only want to return element zero, but if the property I was querying were an array, I would probably be iterating through it or doing some other operation.</p>



<p class="wp-block-paragraph">So the final step here is to add the value of our user’s display name and the value of the “manager” property as a KeyValuePair in my Dictionary, and move on to the next SearchResult. Once we’ve iterated through the entire collection, we can simply return our Dictionary.</p>



<p class="wp-block-paragraph"><a href="https://static.dmcinfo.com/services/digital-workplace-solutions/microsoft-consulting-services">Learn more about our Microsoft Consulting Services</a></p>
<p>The post <a href="https://static.dmcinfo.com/blog/25759/querying-the-active-directory/">Querying the Active Directory</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Connecting Custom Applications to the Factory Floor</title>
		<link>https://static.dmcinfo.com/blog/26086/connecting-custom-applications-to-the-factory-floor/</link>
		
		<dc:creator><![CDATA[Jon Carson]]></dc:creator>
		<pubDate>Fri, 18 Dec 2015 10:31:29 +0000</pubDate>
				<category><![CDATA[PC Application Development]]></category>
		<category><![CDATA[PLC]]></category>
		<category><![CDATA[Siemens PLC]]></category>
		<category><![CDATA[Web Application Development]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C# .NET Application Development]]></category>
		<category><![CDATA[Custom Applications]]></category>
		<category><![CDATA[MS Visual Studio/.NET]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/26086/connecting-custom-applications-to-the-factory-floor/</guid>

					<description><![CDATA[<p>DMC has expertise in both industrial and PC-based software development. In other words, we do a great deal of projects involving PLCs; but we also write plenty of complex PC-based apps. But my personal favorites are projects that combine the two. We’re seeing them more and more. Don’t get me wrong, off the shelf solutions [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/26086/connecting-custom-applications-to-the-factory-floor/">Connecting Custom Applications to the Factory Floor</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">DMC has expertise in both industrial and PC-based software development. In other words, we do a great deal of projects involving PLCs; but we also write plenty of complex PC-based apps. But my personal favorites are projects that combine the two.</p>



<p class="wp-block-paragraph">We’re seeing them more and more. Don’t get me wrong, off the shelf solutions are great, and should be used wherever they make sense. But sometimes they don’t fit all of the requirements our customers need. Here are some examples I’ve encountered over the past few months where a custom PC app made the most sense in an industrial setting:</p>



<p class="wp-block-paragraph">1.&nbsp;&nbsp; &nbsp;A program that automatically parses CAD drawings of a part, and then sends the resulting data to a PLC.<br>
2.&nbsp;&nbsp; &nbsp;Multiple offsite PLCs sending Ethernet packets over a cellular modem, to a server-side application that received, parsed, and logged the data.<br>
3.&nbsp;&nbsp; &nbsp;A web-based interface that translate data back and forth between a custom SQL server and multiple PLCs.</p>



<p class="wp-block-paragraph">So we’ve established there are situations where a custom app makes sense. But how does one write this type of program? What tools are out there to connect the dots? As it turns out, there are plenty! Here are some of my favorites:</p>



<p class="wp-block-paragraph"><strong><a href="https://github.com/dotnetprojects/DotNetSiemensPLCToolBoxLibrary" target="_blank">Dot Net PLC Toolbox&nbsp;</a></strong><br>
Believe it or not, there’s actually a pretty strong community of .NET developers interested in interfacing to PLCs. One of my favorite open-source libraries is the Dot Net PLC Toolbox. This in-depth, free library allows .NET apps to parse PLC projects, as well as communicate, read tags, and go online. Last year I personally was involved with using this toolbox to create an open-source <a href="https://github.com/boriz/s7-diff-merge" target="_blank">S7 Source Control Utility</a>.</p>



<p class="wp-block-paragraph"><strong>InGear Drivers </strong><br>The guys over at InGear have created easy-to-use .NET drivers for Siemens, OPC, and more. Sure, there are free tools available, but sometimes it’s nice to pay for a product just so you have a support team to rely on when you need them.</p>



<p class="wp-block-paragraph"><a href="http://jamod.sourceforge.net/" target="_blank"><strong>Jamod</strong></a><br>
Most of our development is built on .NET, but sometimes client requirements dictate another language like Java. This is where a library like Jamod can be handy. Jamod is a Java library written for Modbus (serial, TCP, or UDP). Since Modbus is such an open protocol, this library makes it easy to connect your Java application to PLCs, drives, smart IO, and more.</p>



<p class="wp-block-paragraph"><a href="https://support.industry.siemens.com/cs/document/108716692/tia-portal-openness%3A-introduction-and-demo-application?dti=0&amp;lc=en-WW" target="_blank"><strong>TIA Portal Openness</strong></a>&nbsp;<br>
For Siemens PLCs in particular, there are official tools available to the interested programmer. With the latest version of TIA Portal, Siemens released an API used to interface with PLC programs. This code library allows developers to “automate” their code development by exporting, modifying, and importing TIA projects. I was pretty familiar with their old software, the <a href="/latest-thinking/blog/id/8446/automating-siemens-s7-and-simotion-tasks-using-c-net">Command Interface</a>, and was excited to see them release a tool for Portal as well.</p>



<p class="wp-block-paragraph">Learn more about DMC&#8217;s <a href="/services/embedded-development-and-embedded-programming"><strong>.NET and automation intelligence capabilities</strong></a>.&nbsp;</p>
<p>The post <a href="https://static.dmcinfo.com/blog/26086/connecting-custom-applications-to-the-factory-floor/">Connecting Custom Applications to the Factory Floor</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Lunch for Business: A Better Way to Lunch</title>
		<link>https://static.dmcinfo.com/blog/26095/lunch-for-business-a-better-way-to-lunch/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Thu, 10 Dec 2015 12:56:05 +0000</pubDate>
				<category><![CDATA[Culture]]></category>
		<category><![CDATA[User Interface Design]]></category>
		<category><![CDATA[Web Application Development]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C# .NET Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/26095/lunch-for-business-a-better-way-to-lunch/</guid>

					<description><![CDATA[<p>DMC had a lunch problem. When noon rolled around, someone would inevitably decide they wanted to go to Chipotle. They&#8217;d get up from their desk and circle around the office, asking everyone they saw if they wanted to jump on the Chipotle train. But &#8220;everyone&#8221; wasn&#8217;t actually everyone, since everyone isn&#8217;t necessarily at their desk [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/26095/lunch-for-business-a-better-way-to-lunch/">Lunch for Business: A Better Way to Lunch</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">DMC had a lunch problem. When noon rolled around, someone would inevitably decide they wanted to go to Chipotle. They&rsquo;d get up from their desk and circle around the office, asking everyone they saw if they wanted to jump on the Chipotle train. But &ldquo;everyone&rdquo; wasn&rsquo;t actually everyone, since everyone isn&rsquo;t necessarily at their desk at 11:58 AM. Some people would be on the phone, others in collaboration rooms. Perhaps they&rsquo;d even be on the other side of the office, asking if anyone wanted to go to Taco Bell! And so your group would get back to DMC, burritos in hand, only to find some very sad people who missed out because they didn&rsquo;t know where you were going.</p>

<p class="wp-block-paragraph">Sam, Sudeep, and I were fed up with this. On our latest&nbsp;<a href="https://static.dmcinfo.com/latest-thinking/blog/id/9042/fedex-day-2015">FedEx Day</a>, which is a day dedicated to fun, internal improvement projects, we decided there had to a better way. An advanced, easy-to-use team communication and collaboration tool that served a single, highly-specialized purpose: to figure out what we wanted to eat.</p>

<p class="wp-block-paragraph">And since we&rsquo;re a creative bunch, we made exactly that and named it Lunch for Business.</p>

<figure class="wp-block-image"><img decoding="async" alt="Lunch for Business Interface" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/l4b.png"  /></figure>

<p class="wp-block-paragraph"><strong>Application Features</strong></p>

<p class="wp-block-paragraph"><span style="line-height: 1.6;">It can be hard to get a large group of people all using the same new tool. That&rsquo;s why our number one goal was to make this stupid simple. It installs with a single click, automatically launches on startup, and lives stowed away in your system tray. &nbsp;</span></p>

<p class="wp-block-paragraph">When you decide that yes, you would very much like a burrito today, you can double click the tray icon, type in &ldquo;Chipotle&rdquo;, and hit suggest. At that moment, everyone currently running Lunch for Business gets a little balloon notification saying that a suggestion has been made. People can then click &ldquo;Join&rdquo; to hop on your bandwagon, or they can make a suggestion of their own.</p>

<p class="wp-block-paragraph">Once you&rsquo;ve joined a lunch spot, you can let people know you&rsquo;re willing to drive others there. You can also click on the lunch spot to launch Google Maps for directions and check out the traffic conditions. When you&rsquo;re ready to go, you can click &ldquo;Leave&rdquo; and everyone in your group will get notified that it&rsquo;s time to head out.</p>

<p class="wp-block-paragraph">Lunch for Business was adopted quickly and has become the de facto way of suggesting places to go eat in the Chicago office. The days of walking around in circles are long gone.&nbsp;<span style="line-height: 1.6;">Aside from fulfilling an extremely important need, the project has been a nice way to check out cool technologies like </span><a href="http://www.asp.net/signalr" style="line-height: 1.6;" target="_blank">SignalR</a><span style="line-height: 1.6;">, </span><a href="http://hangfire.io/" style="line-height: 1.6;" target="_blank">Hangfire</a><span style="line-height: 1.6;">, and the </span><a href="https://developers.google.com/maps/?hl=en" style="line-height: 1.6;" target="_blank">Google Maps API</a><span style="line-height: 1.6;">.</span></p>

<p class="wp-block-paragraph">We also used a variety of familiar favorites to build the application, including:</p>

<ul class="wp-block-list">
 <li>C#</li>
 <li>.NET</li>
 <li>WebSockets</li>
 <li><a href="/services/application-development/web-application-development/aspnet-and-aspnet-mvc">ASP.NET MVC</a></li>
 <li>WPF</li>
 <li>Microsoft SQL Server</li>
</ul>

<p class="wp-block-paragraph"><strong>A Closer Look at DMC&apos;s Noshing Preferences</strong></p>

<p class="wp-block-paragraph">As an added bonus, keeping track of lunch spots has let us keep statistics on where DMC likes to eat. Chipotle and Mariano&rsquo;s dominate the list, with one of the two being suggested half of the time. But, thankfully, the other half includes a much more diverse list of places in our neighborhood. DMC clearly has some favorites, but we still like to explore different options.</p>

<figure class="wp-block-image"><img decoding="async" alt="Lunch For Business Suggestion Stats" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/wheredmceats.png"  /></figure>

<p class="wp-block-paragraph"><a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming">Learn more about DMC&apos;s Custom Software and Hardware Development services.</a></p>
<p>The post <a href="https://static.dmcinfo.com/blog/26095/lunch-for-business-a-better-way-to-lunch/">Lunch for Business: A Better Way to Lunch</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Visual Studio 2015 Debugging Tips</title>
		<link>https://static.dmcinfo.com/blog/26307/visual-studio-2015-debugging-tips/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Fri, 11 Sep 2015 16:29:22 +0000</pubDate>
				<category><![CDATA[PC Application Development]]></category>
		<category><![CDATA[Web Application Development]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C# .NET Application Development]]></category>
		<category><![CDATA[MS Visual Studio/.NET]]></category>
		<category><![CDATA[Software Development]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/26307/visual-studio-2015-debugging-tips/</guid>

					<description><![CDATA[<p>We had a great summer here at DMC&#8217;s Chicago office. We got to watch the Air and Water Show at Belmont Harbor, go to the Circus, drink on a boat, and play some beach volleyball. However, for a .NET developer like me the real highlight of the summer was the release of Visual Studio 2015. [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/26307/visual-studio-2015-debugging-tips/">Visual Studio 2015 Debugging Tips</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><p style="line-height: 20.8px;">We had a great summer here at DMC&#8217;s Chicago office. We got to <a href="/latest-thinking/blog/id/9083/messaging-at-the-marina-for-dmc-chicagos-adcm">watch the Air and Water Show at Belmont Harbor</a>, <a href="/latest-thinking/blog/id/9078/dmc-goes-to-the-circus">go to the Circus</a>, <a href="/latest-thinking/blog/id/9068/beer-on-a-boat-exactly-as-fun-as-it-sounds">drink on a boat</a>, and <a href="/latest-thinking/blog/id/9054/dmc-beach-volleyball">play some beach volleyball</a>. However, for a <a href="/services/application-development">.NET developer</a> like me the real highlight of the summer was the release of <a href="https://www.visualstudio.com/en-us/products/vs-2015-product-editions.aspx" target="_blank">Visual Studio 2015</a>. VS2015 was released officially on July 20th, and over the past several weeks I&#8217;ve gotten a chance to dig into it and explore all of the great new features. This new version of Visual Studio includes many improvements ranging from cross-platform development tools to a major update in the ASP.NET platform. However, the features that I&#8217;ve been enjoying the most are the enhanced debugging and diagnostics tools.</p></p>



<p class="wp-block-paragraph"><p style="line-height: 20.8px;">Below are a few tips and tricks that I&#8217;ve learned about debugging in Visual Studio 2015 that I think every developer should know about:</p></p>



<p class="wp-block-paragraph"><p style="line-height: 20.8px;"><strong>LINQ Expressions in Debug Windows</strong><br>
LINQ expressions now work in debug windows. You may not have been aware of this limitation before, but all previous versions of Visual Studio did not allow for LINQ expressions within debug windows. So for instance if I wanted to do a quick LINQ query in my Watch list to narrow down a list of 100 elements to the few elements that I actually wanted to look at I couldn&#8217;t. Now I can!</p></p>



<p class="wp-block-paragraph"><p style="line-height: 20.8px;"><img decoding="async" alt="Visual Studio 2015 Linq Expressions in Debugger Window" class="MobileImage" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/vs2015-linq-expressions-in-debugger-window_1.png"><br>
<em>LINQ expressions working great in Visual Studio 2015&#8230;</em></p></p>



<p class="wp-block-paragraph"><p style="line-height: 20.8px;"><em><img decoding="async" alt="Visual Studio 2013 Linq Expressions in Debugger Window" class="MobileImage" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/vs2013-linq-expressions-in-debugger-window.png"><br>
&#8230;not so well in Visual Studio 2013.</em></p></p>



<p class="wp-block-paragraph"><p style="line-height: 20.8px;"><strong>PerfTips</strong><br>
This was a feature I didn&#8217;t even know I needed until I had it. PerfTips give you in-line information about the performance of your code as you are stepping through it in the debugger. This makes it very easy to time how long the execution of a block or line of code is taking without having to deal with adding in debug timers and writing to the console. Its super simple and effective. You can also click on the PerfTip to bring up information about events and resource usage related to that PerfTip in the Diagnostics Tools Window.</p></p>



<p class="wp-block-paragraph"><p style="line-height: 20.8px;"><img decoding="async" alt="Visual Studio 2015 PerfTips" class="MobileImage" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/vs2015-perftips.png"><br>
<em>PerfTips in action. In this case, we can see that it took 5 milliseconds to execute the previous line.</em></p></p>



<p class="wp-block-paragraph"><p style="line-height: 20.8px;"><strong>Diagnostic Tools Window</strong><br>
This is a brand new window that is useful for debugging performance issues while your application is running. The Diagnostic Tools Window makes it easy to observe the memory and CPU usage of your application by charting the resource usage on live charts. You can also take snapshots of your applications memory usage in a single click and then compare the snapshots to find memory leaks.</p></p>



<p class="wp-block-paragraph"><p style="line-height: 20.8px;"><img decoding="async" alt="Visual Studio 2015 Diagnostic Tools Window" class="MobileImage" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/vs2015-diagnostic-tools-window.png"><br>
<em>A series of memory snapshots taken in the Diagnostic Tools Window indicates that this program has a memory leak.</em></p></p>



<p class="wp-block-paragraph"><p style="line-height: 20.8px;"><strong>Live Visual Tree</strong><br>
Yet another brand new window in VS2015. This tool allows you to explore the visual tree of a XAML window (or HTML document) while the application is running. I&#8217;ve been using tools like WPF Inspector and Snoop in the past to accomplish UI debugging in WPF applications, but I always welcome the opportunity to use an integrated tool. If you are someone who is constantly tweaking user interfaces in XAML and trying to figure out why that MVVM binding isn&#8217;t working then you should definitely check this out.</p></p>



<p class="wp-block-paragraph"><p style="line-height: 20.8px;"><img decoding="async" alt="Visual Studio 2015 Live Visual Tree" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/vs2015-live-visual-tree.png"><br>
<em>The Live Visual Tree lets you explore the live XAML tree and easily trace down the source code for any element.</em></p></p>



<p class="wp-block-paragraph"><p style="line-height: 20.8px;">To learn more about Visual Studio and .NET check out other <a href="https://static.dmcinfo.com/blog/tag/ms-visual-studio-net/">DMC blog posts</a> or our <a href="/services/application-development">Custom Software development services</a>.</p></p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://static.dmcinfo.com/blog/26307/visual-studio-2015-debugging-tips/">Visual Studio 2015 Debugging Tips</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Automating Web Development &#8211; Tools</title>
		<link>https://static.dmcinfo.com/blog/26709/automating-web-development-tools/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Tue, 07 Apr 2015 12:27:34 +0000</pubDate>
				<category><![CDATA[Web Application Development]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Dot Net Nuke]]></category>
		<category><![CDATA[HTML and CSS]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Web]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/26709/automating-web-development-tools/</guid>

					<description><![CDATA[<p>I’ve been working on a new DNN skin for a while now and much progress is being made. Along the way, I’ve learned about tools that can help speed up website development drastically. In this blog post, I’ll give an overview of these tools and how to use them by themselves and together to harness [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/26709/automating-web-development-tools/">Automating Web Development &#8211; Tools</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I’ve been working on a new DNN skin for a while now and much progress is being made. Along the way, I’ve learned about tools that can help speed up website development drastically. In this blog post, I’ll give an overview of these tools and how to use them by themselves and together to harness the power of automation and simplify development tasks.</p>



<h2 id="h-tools" class="wp-block-heading">Tools</h2>



<ul class="wp-block-list">
<li><a href="#ruby">Ruby</a></li>



<li><a href="#sass-or-less">Sass (or Less)</a></li>



<li><a href="#nodejs">Node.js</a></li>



<li><a href="#npm">npm</a></li>



<li><a href="#bower">Bower</a></li>



<li><a href="#grunt-or-gulp">Grunt or gulp</a></li>
</ul>



<h3 id="ruby" class="wp-block-heading">Ruby</h3>



<p class="wp-block-paragraph">We won’t be using Ruby as a programming language, but we will be needing it to install SASS.</p>



<p class="wp-block-paragraph">If you’re on Windows, download the <a href="https://rubyinstaller.org/" type="link" id="https://rubyinstaller.org/" target="_blank" rel="noreferrer noopener">latest version of Ruby</a></p>



<p class="wp-block-paragraph">If you’re on Linux or OS X, there are <a href="https://rvm.io/rvm/install" type="link" id="https://rvm.io/rvm/install" target="_blank" rel="noreferrer noopener">instructions you can follow</a></p>



<p class="wp-block-paragraph">Or, after installing cURL, run this in a terminal window:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">Bash</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>\curl -sSL https://get.rvm.io/ | bash</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">\curl</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-sSL</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">https://get.rvm.io/</span><span style="color: #D4D4D4"> | </span><span style="color: #DCDCAA">bash</span></span></code></pre></div>



<p class="wp-block-paragraph">Once Ruby has finished installing, no matter what platform you’re on, open a terminal window and run</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">Bash</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>ruby -v</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">ruby</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-v</span></span></code></pre></div>



<p class="wp-block-paragraph">to ensure it has installed properly.</p>



<h3 id="sass-or-less" class="wp-block-heading">Sass (Syntactically Awesome Style Sheets) or Less</h3>



<p class="wp-block-paragraph">Sass is basically CSS with a ton of awesome features layered on top. Using Sass, which compiles to clean and efficient CSS, one can make use of extended abilities like variables, mixing, inline imports, and more.</p>



<p class="wp-block-paragraph">There is another CSS extension called Less, which is an alternative to Sass. I prefer Sass, but you could definitely adapt this tutorial to work with Less as well.</p>



<p class="wp-block-paragraph">Anyhow, now that Ruby is installed and ready to go, installing Sass is easy.</p>



<p class="wp-block-paragraph">In a terminal window, type</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">Bash</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>gem install sass</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">gem</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">install</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">sass</span></span></code></pre></div>



<p class="wp-block-paragraph">Once that is finished, run</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">Bash</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sass -v</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">sass</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-v</span></span></code></pre></div>



<p class="wp-block-paragraph">to ensure it has installed properly.</p>



<h3 id="nodejs" class="wp-block-heading">Node.js</h3>



<p class="wp-block-paragraph">Node.js is tool that allows one to write simple JavaScript programs that create powerful applications.</p>



<p class="wp-block-paragraph">We’ll be using Node.js to power npm (node package manager), Bower, and Grunt.</p>



<p class="wp-block-paragraph"><a href="https://nodejs.org/download/" type="link" id="https://nodejs.org/download/" target="_blank" rel="noreferrer noopener">Grab the proper download for your platform</a></p>



<p class="wp-block-paragraph">To install Node.js on Windows or OS X, simply run the installers.</p>



<p class="wp-block-paragraph">On Linux, you can build Node.js by using these steps:</p>



<p class="wp-block-paragraph">Extract the downloaded archive and open a terminal window</p>



<p class="wp-block-paragraph">1. Navigate to where you extracted the archive</p>



<p class="wp-block-paragraph">2. Run</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">JavaScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>./configure</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">./</span><span style="color: #9CDCFE">configure</span></span></code></pre></div>



<p class="wp-block-paragraph">3. Run and wait patiently</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">JavaScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>make</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #9CDCFE">make</span></span></code></pre></div>



<p class="wp-block-paragraph">4. Run</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">JavaScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>sudo make install</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #9CDCFE">sudo</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">make</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">install</span></span></code></pre></div>



<p class="wp-block-paragraph">And you’ll be all set with Node.js.</p>



<h3 id="npm" class="wp-block-heading">npm</h3>



<p class="wp-block-paragraph">npm is the official package manager for Node.js. What this means is that using npm, one can install hundreds of different applications and tools that are built with Node.js.</p>



<p class="wp-block-paragraph">We’ll be using npm to install Bower and Grunt.</p>



<p class="wp-block-paragraph">npm comes installed with Node.js, so there are no additional steps required to install it.</p>



<h3 id="bower" class="wp-block-heading">Bower</h3>



<p class="wp-block-paragraph">Bower, much like npm, is a package manager. However, npm only deals with Node.js packages while Bower titles itself “a package manager for the web.” Using Bower, one can run a simple terminal command to download and install many different web libraries or frameworks, such as jQuery, Bootstrap, FontAwesome, and more.</p>



<p class="wp-block-paragraph">To install Bower, open a terminal window and type:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">JavaScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>npm install -g bower</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #9CDCFE">npm</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">install</span><span style="color: #D4D4D4"> -</span><span style="color: #9CDCFE">g</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">bower</span></span></code></pre></div>



<p class="wp-block-paragraph">(The -g flag is to install bower globally, so we can call it from the command line anywhere)</p>



<h3 id="grunt-or-gulp" class="wp-block-heading">Grunt or gulp</h3>



<p class="wp-block-paragraph">Grunt is a task runner that performs the time-consuming, repetitive tasks that come along with website development like minification, SASS compilation, and more.&nbsp;</p>



<p class="wp-block-paragraph">Thanks to npm, Grunt is just as easy to install as Bower:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">JavaScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>npm install -g grunt-cli</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #9CDCFE">npm</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">install</span><span style="color: #D4D4D4"> -</span><span style="color: #9CDCFE">g</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">grunt</span><span style="color: #D4D4D4">-</span><span style="color: #9CDCFE">cli</span></span></code></pre></div>



<p class="wp-block-paragraph">gulp (don’t you ever capitalize that g) is a similar tool that <em>should</em> provide better performance than Grunt because it uses Node.js’s streams.</p>



<p class="wp-block-paragraph">npm comes in handy once again. Install gulp with:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">JavaScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>npm install -g gulp</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #9CDCFE">npm</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">install</span><span style="color: #D4D4D4"> -</span><span style="color: #9CDCFE">g</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">gulp</span></span></code></pre></div>



<h2 id="h-beginning-automation" class="wp-block-heading">Beginning Automation</h2>



<p class="wp-block-paragraph">Now that we have all of the tools we need to begin, we can finally start creating an automated build system.</p>



<p class="wp-block-paragraph">There are tasks associated with web development that quickly become repetitive and mundane. Thankfully, we will no longer have to do these manually!</p>



<p class="wp-block-paragraph">The tasks that we can now automate are (in no particular order):</p>



<ul class="wp-block-list">
<li>Sass (or Less) compilation (converting our Sass or Less to standard CSS)</li>



<li>Concatenation (combining multiple files into one)</li>



<li>Minification (smushing text together to reduce the size, making it load faster)</li>



<li>Linting (automatically checking code for errors)</li>



<li>Copying of files (like fonts)</li>



<li>Adding vendor-specific prefixes to our CSS (ensuring compatibility across browsers)</li>



<li>Detecting features that we require a user’s browser to have</li>



<li>More that I can’t think of!</li>
</ul>



<p class="wp-block-paragraph">And best of all, the build system will be smart enough to understand when a particular file changes to prevent rebuilding the entire thing.</p>



<p class="wp-block-paragraph">Stay tuned for the next article! For now, you can always take a look at DMC&#8217;s <a href="/services/application-development/web-application-development">Web Application Development</a> services, where we can harness the technologies outlined above for your needs.</p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://static.dmcinfo.com/blog/26709/automating-web-development-tools/">Automating Web Development &#8211; Tools</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>VR Labyrinth: Exploring the Tilt Table with an Oculus Rift</title>
		<link>https://static.dmcinfo.com/blog/27524/vr-labyrinth-exploring-the-tilt-table-with-an-oculus-rift/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Thu, 22 May 2014 17:08:27 +0000</pubDate>
				<category><![CDATA[Culture]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/27524/vr-labyrinth-exploring-the-tilt-table-with-an-oculus-rift/</guid>

					<description><![CDATA[<p>If you have been following DMC I’m sure you’ve seen or heard of our awesome tilt table demo. The latest big news is that our demo has made a leap into the future. That’s right, were talking about Virtual Reality! Not those silly adverts from the 80’s; now you can fully explore the Labyrinth generated [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/27524/vr-labyrinth-exploring-the-tilt-table-with-an-oculus-rift/">VR Labyrinth: Exploring the Tilt Table with an Oculus Rift</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">If you have been following DMC I’m sure you’ve seen or heard of our awesome <a href="https://static.dmcinfo.com/blog/27524/vr-labyrinth-exploring-the-tilt-table-with-an-oculus-rift/">tilt table demo</a>. The latest big news is that our demo has made a leap into the future. That’s right, were talking about Virtual Reality! Not those silly adverts from the 80’s; now you can fully explore the Labyrinth generated by our tilt table using an Oculus Rift. Check out the video below to learn more about the <a href="/latest-thinking/blog/id/8786/fed-ex-day-2014">FedEx Day project</a> Grant and I worked on and see it in action.</p>



<p class="wp-block-paragraph"><iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/Htq_SPVcS8c" width="560"></iframe></p>
<p>The post <a href="https://static.dmcinfo.com/blog/27524/vr-labyrinth-exploring-the-tilt-table-with-an-oculus-rift/">VR Labyrinth: Exploring the Tilt Table with an Oculus Rift</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Dynamic Database-Driven Validation Ranges in ASP.NET MVC</title>
		<link>https://static.dmcinfo.com/blog/27560/dynamic-database-driven-validation-ranges-in-asp-net-mvc/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Tue, 13 May 2014 13:12:16 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/27560/dynamic-database-driven-validation-ranges-in-asp-net-mvc/</guid>

					<description><![CDATA[<p>Last week I was working on a project using the ASP.NET MVC 4 framework.The client required some of their form fields to have range limits that would generate a visual warning but not prevent a user from submitting data. The tricky part was that they wanted the range limits to be configured in a database [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/27560/dynamic-database-driven-validation-ranges-in-asp-net-mvc/">Dynamic Database-Driven Validation Ranges in ASP.NET MVC</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Last week I was working on a project using the ASP.NET MVC 4 framework.The client required some of their form fields to have range limits that would generate a visual warning but not prevent a user from submitting data. The tricky part was that they wanted the range limits to be configured in a database table so that the limits could be changed easily on the fly.</p>



<p class="wp-block-paragraph">Normally I would do this by simply throwing a Data Annotation Range Attribute on my model field and then using a ValidationMessageFor HTML Helper in my view and call it a day, but in this case that solution did not meet the client&#8217;s requirements. Using the simple approach above would not allow for configurable ranges since attribute properties have to be hard coded.</p>



<p class="wp-block-paragraph">My next standard approach was to create a custom range checking attribute to use in my model. This attribute would include the logic for pulling the range limits from the database. However, this approach proved to be somewhat flawed since every time a field with this attribute was rendered in a view, an extra database query would be required, and that seemed somewhat excessive.</p>



<p class="wp-block-paragraph">My first reaction whenever I notice excessive database queries is to see how I can use Output Caching. The ASP.NET MVC framework makes caching very easy to do: since the limit values would only be changing every few days, it seemed like a perfect opportunity to leverage Output Caching. So I ripped out all of the attributes that I had added to my model and came up with a solution that consists of the following pieces:</p>



<p class="wp-block-paragraph">1) A controller action with caching enabled that retrieves the limits for a specific property. In this case I made a controller with a single action just for this purpose. The controller extends the BaseController class that gives it access to the database access function called GetRangeLimitsForField. The controller action GetFieldRangeLimits chaches its results for five minutes and varies by the field parameter. If you don&#8217;t set the VaryByParam properly, then the action will end up caching a value for one field and returning that value for all fields. I also created a DataFields enum that is essentially a list of all fields that I would ever need to set validation limits on, and I created a RangeLimitViewModel as well (which is included below the controller code).</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">C#</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>public class RangeLimitController : BaseController
{
    &#91;OutputCache(Duration = 300, VaryByParam = "field")&#93;
    public ActionResult GetFieldRangeLimits(DataFields field)
    {
        var rangeLimitViewModel = new RangeLimitViewModel()
        {
            Field = field
        };

        var rangeLimits = this.GetRangeLimitsForField(field);

        if (rangeLimits != null)
        {
            rangeLimitViewModel.LowerLimit = rangeLimits.LowerLimit;
            rangeLimitViewModel.UpperLimit = rangeLimits.UpperLimit;
        }

        return PartialView("_RangeLimit", rangeLimitViewModel);
    }
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">RangeLimitController</span><span style="color: #D4D4D4"> : </span><span style="color: #4EC9B0">BaseController</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">    &#91;</span><span style="color: #4EC9B0">OutputCache</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">Duration</span><span style="color: #D4D4D4"> = </span><span style="color: #B5CEA8">300</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">VaryByParam</span><span style="color: #D4D4D4"> = </span><span style="color: #CE9178">&quot;field&quot;</span><span style="color: #D4D4D4">)&#93;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ActionResult</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">GetFieldRangeLimits</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">DataFields</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">field</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">    {</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">rangeLimitViewModel</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">new</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">RangeLimitViewModel</span><span style="color: #D4D4D4">()</span></span>
<span class="line"><span style="color: #D4D4D4">        {</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">Field</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">field</span></span>
<span class="line"><span style="color: #D4D4D4">        };</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">rangeLimits</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">this</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">GetRangeLimitsForField</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">field</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">rangeLimits</span><span style="color: #D4D4D4"> != </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">        {</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">rangeLimitViewModel</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">LowerLimit</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">rangeLimits</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">LowerLimit</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">rangeLimitViewModel</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">UpperLimit</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">rangeLimits</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">UpperLimit</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">        }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">PartialView</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;_RangeLimit&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">rangeLimitViewModel</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">2) A partial view that generates some client-side attributes that store the limits for a field. This partial view uses the RangeLimitViewModel that is created in the GetFieldRangeLimits action.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">C#</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>@model RangeLimitViewModel

data-limit-field="@Model.Field"

@if (Model.LowerLimit.HasValue)
{
    &lt;text>data-limit-lower="@Model.LowerLimit.Value"&lt;/text>
}

@if (Model.UpperLimit.HasValue)
{
    &lt;text>data-limit-upper="@Model.UpperLimit.Value"&lt;/text>
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #9CDCFE">@model</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">RangeLimitViewModel</span></span>
<span class="line"></span>
<span class="line"><span style="color: #9CDCFE">data</span><span style="color: #D4D4D4">-</span><span style="color: #9CDCFE">limit</span><span style="color: #D4D4D4">-</span><span style="color: #9CDCFE">field</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;@Model.Field&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">@if</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">Model</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">LowerLimit</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">HasValue</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">    &lt;</span><span style="color: #9CDCFE">text</span><span style="color: #D4D4D4">&gt;</span><span style="color: #9CDCFE">data</span><span style="color: #D4D4D4">-</span><span style="color: #9CDCFE">limit</span><span style="color: #D4D4D4">-</span><span style="color: #9CDCFE">lower</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;@Model.LowerLimit.Value&quot;</span><span style="color: #D4D4D4">&lt;/</span><span style="color: #9CDCFE">text</span><span style="color: #D4D4D4">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">@if</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">Model</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">UpperLimit</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">HasValue</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">    &lt;</span><span style="color: #9CDCFE">text</span><span style="color: #D4D4D4">&gt;</span><span style="color: #9CDCFE">data</span><span style="color: #D4D4D4">-</span><span style="color: #9CDCFE">limit</span><span style="color: #D4D4D4">-</span><span style="color: #9CDCFE">upper</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;@Model.UpperLimit.Value&quot;</span><span style="color: #D4D4D4">&lt;/</span><span style="color: #9CDCFE">text</span><span style="color: #D4D4D4">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">3) A few simple JQuery functions that target any text boxes contained within divs that have the range limit attributes and that highlight the text boxes if their value goes out of the specified range.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">JavaScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>function checkIfInputIsInRange(inputBox, fieldName, lowerLimit, upperLimit) {
    var currentValue = $(inputBox).val();
    var numberValue = parseFloat(currentValue);

    if (currentValue === "" || isNaN(numberValue)) {
        $(inputBox).removeClass("out-of-range");
        return;
    }

    if ((!isNaN(lowerLimit) &amp;&amp; numberValue &lt; lowerLimit) ||
        (!isNaN(upperLimit) &amp;&amp; numberValue > upperLimit)) {
        $(inputBox).addClass("out-of-range");
    } else {
        $(inputBox).removeClass("out-of-range");
    }
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">function</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">checkIfInputIsInRange</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">inputBox</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">fieldName</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">lowerLimit</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">upperLimit</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">currentValue</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">$</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">inputBox</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">val</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">numberValue</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">parseFloat</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">currentValue</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">currentValue</span><span style="color: #D4D4D4"> === </span><span style="color: #CE9178">&quot;&quot;</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">isNaN</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">numberValue</span><span style="color: #D4D4D4">)) {</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">$</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">inputBox</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">removeClass</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;out-of-range&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> ((!</span><span style="color: #DCDCAA">isNaN</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">lowerLimit</span><span style="color: #D4D4D4">) &amp;&amp; </span><span style="color: #9CDCFE">numberValue</span><span style="color: #D4D4D4"> &lt; </span><span style="color: #9CDCFE">lowerLimit</span><span style="color: #D4D4D4">) ||</span></span>
<span class="line"><span style="color: #D4D4D4">        (!</span><span style="color: #DCDCAA">isNaN</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">upperLimit</span><span style="color: #D4D4D4">) &amp;&amp; </span><span style="color: #9CDCFE">numberValue</span><span style="color: #D4D4D4"> &gt; </span><span style="color: #9CDCFE">upperLimit</span><span style="color: #D4D4D4">)) {</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">$</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">inputBox</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">addClass</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;out-of-range&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    } </span><span style="color: #C586C0">else</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">$</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">inputBox</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">removeClass</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;out-of-range&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">4) And a CSS class to highlight a text box with a red border.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">CSS</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>.out-of-range,
.out-of-range:hover {
    border-color: red;
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D7BA7D">.out-of-range</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D7BA7D">.out-of-range:hover</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">border-color</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">red</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">And now you could use the functionality like this in a view:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">C#</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>&lt;div @{ Html.RenderAction("GetFieldRangeLimits", "RangeLimit",
        new { field = DataFields.ExampleField }); }>
    @Html.EditorFor(model => model.ExampleField)
&lt;/div>

&lt;script type="text/javascript">
    configureLimitInputs();
&lt;/script></textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">&lt;</span><span style="color: #9CDCFE">div</span><span style="color: #D4D4D4"> @{ </span><span style="color: #9CDCFE">Html</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">RenderAction</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;GetFieldRangeLimits&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;RangeLimit&quot;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">new</span><span style="color: #D4D4D4"> { </span><span style="color: #9CDCFE">field</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">DataFields</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">ExampleField</span><span style="color: #D4D4D4"> }); }&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">@Html</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">EditorFor</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">model</span><span style="color: #D4D4D4"> =&gt; </span><span style="color: #9CDCFE">model</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">ExampleField</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">&lt;/</span><span style="color: #9CDCFE">div</span><span style="color: #D4D4D4">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">script</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">type</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;text/javascript&quot;</span><span style="color: #D4D4D4">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">configureLimitInputs</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">&lt;/</span><span style="color: #9CDCFE">script</span><span style="color: #D4D4D4">&gt;</span></span></code></pre></div>



<p class="wp-block-paragraph">&nbsp;</p>
<p>The post <a href="https://static.dmcinfo.com/blog/27560/dynamic-database-driven-validation-ranges-in-asp-net-mvc/">Dynamic Database-Driven Validation Ranges in ASP.NET MVC</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>DMC Highlight Cam Project</title>
		<link>https://static.dmcinfo.com/blog/27581/dmc-highlight-cam-project/</link>
		
		<dc:creator><![CDATA[Jesse Batsche]]></dc:creator>
		<pubDate>Wed, 07 May 2014 11:00:29 +0000</pubDate>
				<category><![CDATA[Culture]]></category>
		<category><![CDATA[PC Application Development]]></category>
		<category><![CDATA[Web Application Development]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C# .NET Application Development]]></category>
		<category><![CDATA[MS Visual Studio/.NET]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/27581/dmc-highlight-cam-project/</guid>

					<description><![CDATA[<p>For Fed Ex Day 2014 Devon, Otto, and I worked on the DMC Highlight Cam Project. The end goal of the DMC Highlight Cam project is three-fold: Fed Ex Day Accomplishments Included: Our team created a successful proof of concept for all required GoPro camera integration functions. We made a clear path toward a refined [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/27581/dmc-highlight-cam-project/">DMC Highlight Cam Project</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">For <a href="/latest-thinking/blog/id/8786/fed-ex-day-2014">Fed Ex Day 2014</a> Devon, Otto, and I worked on the DMC Highlight Cam Project.</p>

<p class="wp-block-paragraph">The end goal of the DMC Highlight Cam project is three-fold:</p>

<ol class="wp-block-list" style="list-style-position:inside;">
 <li>Have a camera mounted so that it can continually record all activity at the ping pong table (or any other place where interesting things *might* happen)</li>
 <li>Have the ability to press a single button when something AWESOME/EXCITING/FUNNY/MEMORABLE happens to capture and archive footage of that awesome event</li>
 <li>When a &ldquo;highlight&rdquo; is identified by the user, automatically transfer the video files for the last X seconds (say 60 seconds, adjustable) off the camera and archive it in some centrally accessible location so that it may be watched as a &ldquo;replay&rdquo; (slow mo, etc.), posted on the website, or compiled into a highlight reel (&ldquo;Best of DMC Ping Pong 2014&rdquo;)</li>
</ol>

<figure class="wp-block-image"><img decoding="async" alt="DMC engineers in Chicago work on the DMC Highlight Cam Project" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/IMG_1392_edited_1.jpg"  /></figure>

<p class="wp-block-paragraph">Fed Ex Day Accomplishments Included:</p>

<ul class="wp-block-list">
 <li>Selecting GoPro Hero 3+ Black Edition as camera
 <ul class="wp-block-list">
  <li>Reason 1: About as high of resolution and high frame rate recording as you can get for the $</li>
  <li>Reason 2: Supports a Wi-Fi interface that allows control of camera and access to data remotely over Wi-Fi</li>
 </ul>
 </li>
 <li>Figuring out how to use natively supported automatic &ldquo;looping&rdquo; recording mode that breaks video into one minute segments, and only keeps the most recent five segments (exactly what we needed for this application to prevent memory card from filling up)</li>
 <li>Implementing a .NET application that leverages the available Wifi interface to do the following:
 <ul class="wp-block-list">
  <li>Power up GoPro Camera</li>
  <li>Apply desired video resolution, frame rate, looping mode configuration settings to camera</li>
  <li>Start video recording</li>
  <li>Wait for a user to press a key to identify an AWESOME highlight event</li>
  <li>When highlight event is identified
  <ul class="wp-block-list">
   <li>Gather a listing of the available video files on the GoPro and identify the two most recent video segments</li>
   <li>Transfer those video files from the HTTP file server hosted by the GoPro to a local disk (archive) location</li>
   <li>Continue recording and wait for user to identify the next highlight event</li>
  </ul>
  </li>
 </ul>
 </li>
 <li>Implementing an Android App with similar (slightly limited) functions to interface/communicate with the GoPro</li>
</ul>

<p class="wp-block-paragraph">Our team created a successful proof of concept for all required GoPro camera integration functions. We made a clear path toward a refined version that will be hosted somewhere on the DMC network and can be controlled through the existing DMC ping pong app.</p>
<p>The post <a href="https://static.dmcinfo.com/blog/27581/dmc-highlight-cam-project/">DMC Highlight Cam Project</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Abstracting an ORM to Use Multiple Backends</title>
		<link>https://static.dmcinfo.com/blog/27702/abstracting-an-orm-to-use-multiple-backends/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Mon, 24 Mar 2014 13:21:01 +0000</pubDate>
				<category><![CDATA[PC Application Development]]></category>
		<category><![CDATA[Web Application Development]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[C# .NET Application Development]]></category>
		<category><![CDATA[MS Visual Studio/.NET]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/27702/abstracting-an-orm-to-use-multiple-backends/</guid>

					<description><![CDATA[<p>Object-relational mappings (ORMs) took the world by storm in the mid-aughts. Obviously there are many advantages to ORMs given their success, but there are some drawbacks. I&#8217;ll explain one particular hurdle that I ran into as well as the steps I took to overcome it. A client had an existing database we needed to interact [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/27702/abstracting-an-orm-to-use-multiple-backends/">Abstracting an ORM to Use Multiple Backends</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Object-relational mappings (ORMs) took the world by storm in the mid-aughts. Obviously there are many advantages to ORMs given their success, but there are some drawbacks. I&#8217;ll explain one particular hurdle that I ran into as well as the steps I took to overcome it.</p>



<p class="wp-block-paragraph">A client had an existing database we needed to interact with using an ORM; this necessitated a database-first approach. Furthermore, this database&#8217;s schema was mirrored in other databases with slight modifications. DMC had to build an application that could talk to all of these databases &#8211; which were 99% similar &#8211; using a single interface, so that new, slightly different schemas could be dropped in without a problem.</p>



<p class="wp-block-paragraph">The problem with a database-first ORM, here Microsoft Entity Framework 5, was that the use of multiple database objects infected the business logic. The schemas were similar enough that a single interface could be abstracted out. The only question after devising this interface was how to implement it using the Entity Framework generated files.</p>



<p class="wp-block-paragraph">Consider a table called Entity, with a field called Property. This schema exists on different database servers with different query strings, and Property is slightly different between the two. For simplicity&#8217;s sake lets say it&#8217;s a number in one database and a numeric string in another database.</p>



<p class="wp-block-paragraph">Interacting with Property with the Entity Framework would require two database models and their associated classes, with one Property class being a float and another Property class being a string. Our interface presents this as a float.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">C#</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>public interface IEntity
{
  float Property { get; set; }
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">IEntity</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">float</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">Property</span><span style="color: #D4D4D4"> { </span><span style="color: #569CD6">get</span><span style="color: #D4D4D4">; </span><span style="color: #569CD6">set</span><span style="color: #D4D4D4">; }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">To interact with both, we create explicit implementations of the interface for the Entity table on a partial class mapped to the Entity class generated by our database-first approach. One implementation of this interface is a pass-through to the first Property member of the generated partial class. The other converts the float to a string before passing the converted value on to the second generated Property member.</p>



<p class="wp-block-paragraph">Now that we have abstracted the Entity table, let&#8217;s abstract the database itself. In Entity Framework, tables are represented as DbSets. DbSet implements IQueryable, which is sufficient for querying the database using Linq. The interface follows.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">C#</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>public interface IDatabase : IDisposable
{
  IQueryable&lt;IEntity> Entity { get; }

  IEntity CreateEntity();
  IEntity Add(IEntity entity);

  int SaveChanges();
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">interface</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">IDatabase</span><span style="color: #D4D4D4"> : </span><span style="color: #4EC9B0">IDisposable</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">IQueryable</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">IEntity</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">Entity</span><span style="color: #D4D4D4"> { </span><span style="color: #569CD6">get</span><span style="color: #D4D4D4">; }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">IEntity</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">CreateEntity</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #4EC9B0">IEntity</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">Add</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">IEntity</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">entity</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">int</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">SaveChanges</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Note that additional Create and Add methods are required since IQueryable does not support these operations.</p>



<p class="wp-block-paragraph">Implementing this interface is as simple as implementing IEntity. Explicitly implement IDatabase on a partial class of Database and pass the required properties from the Entity Framework-generated class to the interface implementation.</p>



<p class="wp-block-paragraph">That&#8217;s it. Note that when implementing an ICollection foreign key property on a table, you will need to cast it as IEnumerable in the interface. This cast is handled implicitly with .NET 4.5.</p>



<p class="wp-block-paragraph">There&#8217;s one more trick, though. The Entity Framework is not smart enough to take namespace into account when mapping code objects to database objects. So if you are implementing IEntity multiple times, each implementation will have to be done within its own assembly and namespace. A good solution architecture is to have an interface project referenced by each implementation project and then finally a factory project that references the interface project and all implementation projects. The factory methods can give you a different implementation of IDatabase based upon some parameter.</p>



<p class="wp-block-paragraph"><a href="/services/embedded-development-and-embedded-programming">Learn more about DMC&#8217;s custom hardware and software development services.</a></p>
<p>The post <a href="https://static.dmcinfo.com/blog/27702/abstracting-an-orm-to-use-multiple-backends/">Abstracting an ORM to Use Multiple Backends</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
