Friday, October 31, 2014

FireAndForget a Task with AggressiveInlining

When working with tasks you will get a warning if you do not use a task returned from a method. However, you might actually want to fire and forget that task. So what do you do?

One option is to create an extension method for your task to mark it as fire and forget. Aside from removing the warning, it also gives you the nice ability to find all usages.

When creating this method it is a good idea to mark it with the aggressive inlining attribute. This will cause the compiler to try and inline the method to try and optimize performance.

Implementation and Unit Test

public static class TaskExtensions
{
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static void FireAndForget(this Task task)
    {
        // Do Nothing
    }
}
 
public class TaskExtensionTests
{
    [Fact]
    public void FireAndForget()
    {
        Task
            .Delay(100)
            .ContinueWith(t =>
            {
                // TODO: Stuff!
            })
            .FireAndForget();
    }
}

Enjoy,
Tom

Thursday, October 30, 2014

Tuesday, October 14, 2014

Share ReSharper and StyleCop Configuration via NuGet

Would you to share your coding style standards between projects?

Tools such as ReSharper and StyleCop both allow you to share your settings files between projects by placing a configuration file in the solution directory. However just sharing those settings across projects in a single solution might not be enough to truly enforce your coding standards for a whole team.

You can share your configuration settings across multiple solutions via a NuGet package. These configuration files can not just be standard content files in your NuGet package, they need to be installed via the init PowerShell script inside of the package.

Init.ps1

param($installPath, $toolsPath, $package)
 
Write-Host "==================================="
Write-Host "Initing: CSharpConventions"
 
# Get the active solution
$solution = Get-Interface $dte.Solution ([EnvDTE80.Solution2])
$solutionDir = Get-Item $solution.FullName
 
# Copy StyleCopy file
$copFileName = "Settings.StyleCop"
$newCopPath = join-path $solutionDir.Directory $copFileName
$oldCopPath = join-path $toolsPath $copFileName
Write-Host "Copying " $oldCopPath " to " $newCopPath
Copy-Item $oldCopPath $newCopPath 
 
# Copy and rename DotSettings file
$newDotPath = $solution.FullName + ".DotSettings"
$oldDotPath = join-path $toolsPath "Solution.sln.DotSettings"
Write-Host "Copying " $oldDotPath " to " $newDotPath
Copy-Item $oldDotPath $newDotPath 
 
Write-Host "Completed: CSharpConventions"
Write-Host "====================================="

NuSpec File

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata>
        <id>CSharpConventions</id>
        <version>1.0.0</version>
        <authors>tdupont</authors>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>
            StyleCop and R# settings file to enforce C# coding standards.
        </description>
    </metadata>
    <files>
        <file src="tools\init.ps1" target="tools\init.ps1" />
        <file src="tools\Settings.StyleCop" 
            target="tools\Settings.StyleCop" />
        <file src="tools\Solution.sln.DotSettings" 
            target="tools\Solution.sln.DotSettings" />
    </files>
</package>

Enjoy,
Tom

Tuesday, October 7, 2014

Set a Property Value from an Expression in .NET

In .NET both Action and Func classes are actually delegates that can be invoked to execute code, whereas the Expression class represents an expression tree that can potentially be compiled into executable code at run time. Expressions are particularly fun because they are malleable, and you can use them dynamically create delegates.

For example, you can create a generic statement that allows you to assign values to properties. This means that one piece of code can use a lambda to select a property for assignment, and another unrelated piece of code can use that expression to dynamically assign the value.

Thanks to AnxiousdeV for coming up with this solution on Stack Overflow.

Test

public class ExpressionTests
{
    public int X { get; set; }
 
    [Fact]
    public void GetSetPropertyAction()
    {
        // Create an expression.
        var expression = GetExpression<ExpressionTests, int?>(c => c.X);
        // Use our extension method to create the action.
        var assignAction = expression.GetSetPropertyAction();
 
        // Set the property.
        assignAction(this, 2);
        // Assert that the value was set correctly.
        Assert.Equal(2, X);
    }
 
    private static Expression<Func<T, U>> GetExpression<T, U>(
        Expression<Func<T, U>> expression)
    {
        // We are only using this method to create an expression.
        return expression;
    }
}
Real Time Web Analytics