Thursday, July 18, 2019

Minimize your app config file

Summary: How to keep application configuration files (app.config, web.config) nice and clean.
We use configuration files to store application settings that can be modified, so we do not need to recompile the application. Some applications have lots of settings, but many of these settings are not likely to change or may only change when the application is rebuilt. In such case, here is a nice technique that will allow you to reduce the size of the config file.

Here is the basic idea:
  1. Create a static configuration class (let's call it Config).
  2. In the Config class, implement static methods to get a configuration property value that either gets it from the application's config file (if the setting is defined in the appSettings section) or uses the passed default (you'd need to implement these methods for different data types).
  3. In the Config class, define the static properties that get initialized by calling the methods mentioned above with the hard-coded defaults. To make it easier to remember, the config file's appSettings keys must be named after the Config class properties.
Now, you can remove the settings that are not very likely to change from the config file and if they need to be changed before the application is updated, simply add them back.

Here is the code:

The configuration class is responsible for initialization of the application settings:
using System;
using System.Configuration;

namespace MyApp.Configuration
{
    public static class Config
    {
        public static string OPERATION_LIST = 
            GetValue("OPERATION_LIST", "Create|Read|Update|Delete|Assign|Revoke|Enable|Disable");

        public static string OBJECT_LIST = 
            GetValue("OBJECT_LIST", "User|Group|Role");

        private static string GetValue
        (
            string keyName,
            string defaultValue = null
        )
        {
            string configValue = ConfigurationManager.AppSettings.Get(keyName);

            if (String.IsNullOrEmpty(configValue))
                return defaultValue;

            return configValue;
        }

        private static int GetValue
        (
            string keyName,
            int defaultValue
        )
        {
            string configValue = ConfigurationManager.AppSettings.Get(keyName);

            if (String.IsNullOrEmpty(configValue))
                return defaultValue;

            return Int32.Parse(configValue);
        }

        private static bool GetValue
        (
            string keyName,
            bool defaultValue
        )
        {
            string configValue = ConfigurationManager.AppSettings.Get(keyName);

            if (String.IsNullOrEmpty(configValue))
                return defaultValue;

            return bool.Parse(configValue);
        }

        private static object GetValue
        (
            string keyName,
            Enum defaultValue,
            Type type
        )
        {
            string configValue = ConfigurationManager.AppSettings.Get(keyName);

            if (String.IsNullOrEmpty(configValue))
                return defaultValue;

            return Enum.Parse(type, configValue);
        }
    }
}
Using an application setting is now as easy as referencing the corresponding configuration class property:
string[] operations = Config.OPERATION_LIST.Split('|')
    .Select(op => op.Trim())
    .ToArray();
string[] objects= Config.OBJECT_LIST.Split('|')
    .Select(op => op.Trim())
    .ToArray();
Notice that we do not need to define these values in the application config file unless we have to modify them before we release an application update, in which case, simply add them to the appSettings section:


  
    
  

I assume this must be obvious but just in case: NEVER HARD CODE SENSITIVE INFORMATION (PASSWORDS, ENCRYPTION KEYS, ETC) IN THE APPLICATION SOURCE CODE.

Okay, I'm done for today.

UPDATE: And here is an even better option: BasicConfiguration.

Wednesday, July 10, 2019

How to get or set a nested class property using C#

Summary: C# methods to set and get nested class property values.
If you need to get a set a value of a nested object property, here is a couple of functions that can help you do it using reflection (.NET 4.7, C#):
/// 
/// Gets the value of a nested object property.
/// 
/// 
/// Project that owns the property.
/// < /param>
/// 
/// Name of the property.
/// < /param>
/// 
/// Property value (or null, if property does not exists).
/// 
/// 
/// 
/// The code assumes that the property exists;
/// if it does not, the code will return null.
/// 
/// 
/// The property does not need to be nested.
/// 
/// 
/// The code handles both class properties and fields.
/// 
/// 
public static object GetPropertyValue
(
    object source, 
    string name
)
{
    if (name.Contains("."))
    {
        var names = name.Split(new char[] { '.' }, 2);

        return GetPropertyValue(GetPropertyValue(source, names[0]), names[1]);
    }
    else
    {
        PropertyInfo prop = null;

        prop = source.GetType().GetProperty(name);

        if (prop != null)
            return prop != null ? prop.GetValue(source) : null;

        FieldInfo field = source.GetType().GetField(name);

        if (field == null) return null;

        return field.GetValue(source);
    }
}

/// 
/// Sets the value of a nested object property.
/// 
/// 
/// Object that owns the property to be set. 
/// < /param>
/// 
/// Name of the property.
/// < /param>
/// 
/// Property value.
/// < /param>
/// 
/// 
/// The code assumes that the property exists;
/// if it does not, the code will do nothing.
/// 
/// 
/// The property does not need to be nested.
/// 
/// 
/// The code handles both class properties and fields.
/// 
/// 
public static void SetPropertyValue
(
    object target,
    string name, 
    object value
)
{
    var names = name.Split('.');

    for (int i = 0; i < names.Length - 1; i++)
    {
        PropertyInfo prop = target.GetType().GetProperty(names[i]);
        if (prop != null)
        {
            target = prop.GetValue(target);
            continue;
        }

        FieldInfo field = target.GetType().GetField(names[i]);
        if (field != null)
        {
            target = field.GetValue(target);
            continue;
        }

        return;
    }

    PropertyInfo targetProp = target.GetType().GetProperty(names.Last());

    if (targetProp != null)
        targetProp.SetValue(target, value);
}

Friday, November 17, 2017

How to rotate a video without re-encoding

Summary: A few tips on video rotation.
If your phone messes up the rotation metadata flag in a video file, download ffmpeg and run the following command:
ffmpeg -i input.mp4 -c copy -metadata:s:v:0 rotate=0 output.mp4
This should fix the problem without re-encoding the video. If it does not, try setting the rotate switch to a different number, such as 90, 180, or 270. For additional information about video orientation MP4 and other video files, check the See also section.

See also:
iPhone recorded videos getting rotated on Windows systems
Rotate a MP4 file, while preserving codec and quality attributes
Rotate mp4 videos without re-encoding
Rotating videos with FFmpeg
How to rotate a video 180° with FFmpeg?

How to fix slow startup for old Photoshop/Premiere Elements apps (on Windows)

Summary: Easy way to fix slow startup issues for older versions of Adobe products (on Windows).
If you have an older version of Adobe video and photo editing products, such as Photoshop Elements or Premiere Elements, you may be irritated with the long startup time, which could take several minutes. Apparently, the applications try to connect to a server that is no longer in service (btw, excellent job, Adobe!), so they wait... and wait... and wait... The good thing is that there seems to be an easy fix for this.

According to the answer to this post, you just need to add the following entry to your hosts file located in the %WINDIR%\System32\Drivers\Etc folder:
127.0.0.1   static.photoshop.com
This solved the problem form my Photoshop Elements 9 and Premiere Elements 13 instances running on Windows 7 (yeah, I know, need to upgrade to Windows 10, but that's a different story).

Enjoy!

Friday, October 20, 2017

Save STDOUT/STDERR to clipboard (and more)

Summary: How to redirect the STDOUT or STDERR stream to clipboard.
Note to self (mostly), in case I forget the command that would redirect standard output or standard error stream and save it on the clipboard.

Redirect STDOUT to clipboard:
command | clip
Redirect STDERR to clipboard:
command 2>&1 | clip
The following will save the contents of the current directory to the clipboard:
dir | clip
Now, let's try the following:
dir xyz: | clip
The clipboard now will hold something like this:
 Volume in drive C is SYSTEM
 Volume Serial Number is 1234-ABCD

 Directory of C:\Windows\SysWOW64
Now, let's redirect STDERR to clipboard:
dir xyz:2>&1 | clip
The clipboard now will hold something like this:
"xyz:" is not a recognized device.
"xyz:" is not a recognized device.
 Volume in drive C is SYSTEM
 Volume Serial Number is 1234-ABCD

 Directory of C:\Windows\SysWOW64

File Not Found
See also:
Forgotten (but Awesome) Windows Command Prompt Features by Scott Hanselman
How to pipe stderr, and not stdout?

Tuesday, August 22, 2017

How to clean up BIN and OBJ folders in a Visual Studio solution

Summary: Some ideas on cleaning up intermediate and output folders in Visual Studio projects.
There may be better (and more elegant) ways of cleaning up the output (BIN) and intermediate (OBJ) folders generated by Visual Studio build process, but the following script is probably the easiest option you can use:

@echo off
rem Delete BIN and OBJ folders from the immediate folder and all subfolders.
rem

rem Switch to the script folder.
cd "%~dp0"

rem Use the following to suppress the 'File Not Found' message if no folders are found.
setlocal enabledelayedexpansion 
for /f "tokens=*" %%G in ('dir /B /AD /S bin 2^>nul') do rmdir /S /Q "%%G"
for /f "tokens=*" %%G in ('dir /B /AD /S obj 2^>nul') do rmdir /S /Q "%%G"

Notice that the script call setlocal enabledelayedexpansion to allow the 2^>nul redirection in the for loops (without it, it would output the "File Not Found" message if the folder and subfolders do not hold the "BIN" or "OBJ" folders.

See also:
How to clean Visual Studio bin and obj folders
I want to delete all bin and obj folders to force all projects to rebuild everything
Want to suppress File not found output
Suppress command line output

Wednesday, April 27, 2016

Rapid prototyping with jsFiddle for web developers

Summary: How to use jsFiddle for building wireframes and rapid prototyping.
Recently, I needed to build interactive prototypes of a web form. I do not own a license of a professional prototyping tool (like Balsamiq, HotGloo, UXPin), so I tired several free online options (namely, iPLOTZ, concept.ly, MockFlow) and appreciated the ease of drag-and-drop; however, making these prototypes respond to interactive events (mouse clicks, selection changes, etc) turned into a hassle.

I also tried a couple of desktop options, but had even less luck with Pencil (couldn't figure out how to make a combo box display multiple entries), Visio 2013 ("Where is the combo box, Lebowski?"), and Blend for Visual Studio 2013 ("You're entering the world of pain!").

I was entertaining an idea of using animations in PowerPoint, when it struck me:
Why not use jsFiddle?
If, after reading the previous sentence, the first question that popped into your mind was "What the heck is jsFiddle?", you may not realize that saying "What the heck!" is really worse than saying "What the hell!". But nonetheless, for those just coming out of a coma:

jsFiddle is a free web-based tool that allows you to quickly test HTML/JavaScript/CSS. But wait, there's more!
Here is what a jsFiddle screen looks like:
You enter HTML, CSS, and JavaScript code into the corresponding panels, click the Run button, and see the result of your work in the window appropriately named Result. It's that simple.

Let's summarize what jsFiddle has to offer:
  • It's free (as in "it ain't cost sh*t").
  • It's web-based (no crap to install).
  • It's not using Adobe Flash, like most other online prototypes do (they still do, don't they?).
  • It uses HTML, CSS and JavaScript (you already know these, right?).
  • It uses a standard web programming model (no need to learn proprietary controls).
  • It supports pretty much every popular JavaScript/CSS framework (yay to jQuery! yay to Bootstrap!).
  • It can incorporate any custom JavaScript/CSS framework (assuming it has a public URL).
  • It keeps versions of your changes (version control by default).
  • You can send a URL of your prototype for a review or do a live demo (with some quirks, though).
  • You can collaborate with others on a prototype (although, I haven't tried).
The bottom line is that using jsFiddle, you can quickly build a prototype and implement the functionality that is only constrained by the limitations of the same technologies your applications uses (JavaScript, CSS, HTML). In the other words, there are no practical constraints. It's almost too good to be true. Why haven't I thought about it before?

Anyway, if you want to build a wireframe or a quick prototype using jsFiddle, do the following:
  1. Create an account (if you don't have one).
  2. Log in and open the editor.
  3. While in the editor, under the Fiddle Meta section on the left side, enter the title and description of your prototype (wireframe). If you do not want to make it public (discoverable via search), leave the title field blank.
  4. Add your HTML, CSS, JavaScript.
  5. Click the Run menu option to preview the functionality.
  6. When you are happy with the result, click the Save (or Update) menu button to keep the changes.
  7. The public link to the fiddle can be found in the Embed Code section of the Embed screen (to open the Embed screen, click the Embed menu option).
If you close jsFiddle and come back, you will find your fiddles in the dashboard (to access the dashboard link from the editor, click your account name in the top right corner of the page). The dashboard shows your public and private fiddles (proper descriptions will make it easier for you to locate private fiddles):
Now, a bit of jsFiddlespeak, if you do not mind.

Visibility: You may have noticed somewhat non-traditional use of the term public. As I mentioned above, public means that a fiddle can be found via a search, and non-public means that to access a fiddle, someone must know the fiddle's URL (non-public fiddles are still open to public).

Baseline: Every time you save a fiddle (via the Save or Update menu option), jsFiddle will create and retain a new version. You can access a specific version of the fiddle by appending the version number to the fiddle's URL. For example, assume that your jsFiddle profile name is jdoe and you make 13 changes to a fiddle with ID qdn9f737, the URLs of the version history will look like these:
https://jsfiddle.net/jdoe/qdn9f737/1/
https://jsfiddle.net/jdoe/qdn9f737/2/
https://jsfiddle.net/jdoe/qdn9f737/3/
...
https://jsfiddle.net/jdoe/qdn9f737/12/
https://jsfiddle.net/jdoe/qdn9f737/13/
The non-versioned URL will correspond to whichever version you set as base (the first version by default) and will look like this:
https://jsfiddle.net/jdoe/qdn9f737/
You can define any version as base by opening this version in the editor and clicking the Set as base menu option (in certain cases, you may need to save the version first).

Finally, a few tips to help you get most out of jsFiddle (these are mostly notes to self, but others may find them handy).

Use the gear buttons (in the right top corners of the corresponding panels) to configure the HTML, CSS, and JavaScript settings. In particular, you can specify the version of HTML (such as HTML 5 or HTML 4.0.1 Strict) to use and а JavaScript framework (such as jQuery 2.2.3 or AngularJS 1.4.8) to include. You can only pick one option from the JavaScript Frameworks and Extensions list, but you can include additional dependencies as external resources.

To include an external resource (other than the framework or extension selected in the JavaScript Frameworks and Extensions list), click the External Resources header in the left pane of the page, paste or type in the URL of the framework file (normally, the resource's CDN address) in the JavaScript/CSS URI field, and click the plus sign. Here are the URLs of the common CDNs: If you want to share your prototype, but do not want others to see the JavaScript/HTML/CSS code, uncheck the HTML, CSS, and JavaScript option under the Tabs heading in the Embed options (notice that the source URL in the Embedded Code section ends with embed/result/):

To make the prototype look better when viewed in the the full screen mode, you may want to limit the maximum width of the page. Enter the code similar to this in the CSS panel:
html {
  max-width: 1200px;
  margin: 0 auto;
  background: #eee; /* Fills the page */
  position: relative; /* Fix for absolute positioning */
}
Have fun!