EnterpriseLibrary.Config for VS2015

With the release of Visual Studio 2015 I’ve updated the EntperiseLibrary.Config V6 extension to support Visual Studio 2015.

You can download it here:

Microsoft.Practices.EnterpriseLibrary.ConfigConsole.V6.VS2015.vsix

Also see my older post about EnterpriseLibrary.Config for VS2013.

Posted in Enterprise Library | Tagged , , , , | 8 Comments

Semantic Logging Single Line Summary Formatter

tl;dr
You can create a single line summary formatter by setting the verbosity threshold to -1:

var singleLineFormatter = new EventTextFormatter(null, null, verbosityThreshold: (EventLevel)(-1), dateTimeFormat: null);
EventListener listener = ConsoleLog.CreateListener(singleLineFormatter);

Recently I was creating an Azure WebJob. The project was already using the Semantic Logging Application Block (SLAB) to log to Azure tables so I wanted to reuse the same logging approach for the WebJob. WebJobs capture the console output and lets you view the job output directly from the WebJobs dashboard which makes using the ConsoleSink a good approach in combination with more structured storage (e.g. Azure Table) if required.

So I just created a simple Console Listener:

EventListener listener = ConsoleLog.CreateListener();

But the output wasn’t exactly what I wanted:

ProviderId : 1234562b-1999-5G31-abe2-5b22bd598765
EventId : 210
Keywords : 2
Level : LogAlways
Message :
Opcode : Info
Task : 65924
Version : 0
Payload : [startDateTime : 10/30/2014 2:16:28 AM]
EventName : JobStartedInfo
Timestamp : 2014-10-30T06:16:28.8690695Z
ProcessId : 12
ThreadId : 117

Sure, all the information is there but each piece is on a new line which made the output hard to read and added many many extra lines to the output log. What I really wanted was an easy to read single line format. At first I thought I might need to create a custom formatter but decided to poke around a bit first.

Out of the Box SLAB supports a verbose format (which is what is shown above) and a summary format (which is a single line and is what I wanted).

There was a small issue, though.

The format used by the default EventTextFormatter is determined by looking at a verbosity threshold. If the threshold is set to EventLevel.LogAlways then the verbose format is used. Also if the EventLevel of the EventEntry is less than or equal to the set verbosity threshold the verbose format will be used. But in this case, I always want to use the single line summary format.

The solution is to set the verbosity threshold to a value so that the EventLevel of the EventEntry is never less than or equal to the verbosity threshold. The EventLevel is an enum with the following values:

    public enum EventLevel
    {
        LogAlways = 0,
        Critical = 1,
        Error = 2,
        Warning = 3,
        Informational = 4,
        Verbose = 5,
    }

We can’t satisfy the condition that we want with a valid enum value but we can set the verbosity threshold to an invalid value (since the enum is backed by an int, .NET is happy to do this for us). This forces SLAB to always use the summary format:

var singleLineFormatter = new EventTextFormatter(null, null, verbosityThreshold: (EventLevel)(-1), dateTimeFormat: null);
EventListener listener = ConsoleLog.CreateListener(singleLineFormatter);

Now all output will be formatted on a single line (and with a bit less information):

EventId : 210, Level : LogAlways, Message : , Payload : [startDateTime : 10/30/2014 2:15:40 AM] , EventName : JobStartedInfo, Timestamp : 2014-10-30T06:15:40.3354494Z, ProcessId : 96, ThreadId : 138

A note of caution: this approach does rely on the knowing the internals of the EventTextFormatter which could change and break this approach. Also, using an invalid enum value could be considered bad form.

Posted in Uncategorized | Tagged , , , | Leave a comment

Unity Registration By Convention For Abstract Types

This post is inspired by this question on Stack Overflow: Can Unity’s “register-by-convention” resolve for abstract classes?  The basic question is: “how can i register my abstract classes and the implementation of each repository specific repository, like with the interfaces?”

The bad news is that there is no facility out of the box in Unity to register Abstract type mappings while the good news is that Unity provides a means to do this with a little coding.

The parameters to the RegisterTypes methods are Funcs which means that we can create our own functions that perform the required registration logic.

For this posting I will assume that the classes to register look something like this:

public abstract class AbstractBase { }

public abstract class AbstractRepository : AbstractBase { }

public class TestRepository : AbstractRepository { }

public class AnotherRepository : AbstractRepository { }

For the mappings AbstractBase will be mapped to TestRepository and AbstractRepository will also be mapped to TestRepository.

Let’s also assume that we want to handle generics:

public abstract class AbstractBase<T> { }

public abstract class AbstractRepository<T> : AbstractBase<T> { }

public class TestRepository<T> : AbstractRepository<T> { }

public class TestRepositoryClosed : AbstractRepository<int> { }

With this as a starting point, the first step is to create the logic that maps from abstract to concrete types:

public static class WithMappingsCustom
{
    private static readonly IEnumerable<Type> EmptyTypes =
        Enumerable.Empty<Type>();

    public static IEnumerable<Type> FromAbstractClass(Type implementationType)
    {
        if (implementationType == null)
        {
            throw new ArgumentNullException("implementationType");
        }

        List<Type> types = null;

        // Recurse over object tree to populate types with the mappedFrom types
        GetImplementedAbstractClassesToMap(implementationType, ref types);

        if (types != null)
        {
            return types;
        }
        else
        {
            return EmptyTypes;
        }
    }

    private static void GetImplementedAbstractClassesToMap(Type type,
        ref List<Type> types)
    {
        var typeInfo = type.GetTypeInfo();

        // Top level type (i.e. "MappedTo") is abstract so skip
        if (typeInfo.IsAbstract && types == null)
        {
            return;
        }

        // If type is a value type or inherits from object then there 
        // is nothing to map to or we have reached the top of the hierarchy
        if (typeInfo.IsValueType || typeInfo.BaseType == typeof(object))
        {
            return;
        }

        Type nextType = typeInfo.BaseType;
        Type nextTypeInfo = typeInfo.BaseType.GetTypeInfo();

        // If the base type is abstract we will create mapping for it
        if (nextTypeInfo.IsAbstract)
        {
            // Special handling for generics otherwise type information is not
            // populated see: 
            // http://msdn.microsoft.com/en-us/library/system.type.fullname.aspx
            if (nextTypeInfo.IsGenericTypeDefinition ||
                (nextTypeInfo.IsGenericType && nextTypeInfo.FullName == null))
            {
                nextType = nextTypeInfo.GetGenericTypeDefinition();
            }

            if (types == null)
            {
                types = new List<Type>();
            }

            types.Add(nextType);
        }

        // Recurse to get other abstract objects in hierarchy so that 
        // we can map one type to multiple abstract base classes
        GetImplementedAbstractClassesToMap(nextType, ref types);
    }
}

The above code looks at the type and walks the BaseType hierarchy to add any abstract types to the list of types that will be used as the “from” value in the mapping. Internally, a lazily instantiated List is used (to avoid object creation if there are no mappings). Iterators could also be used instead but for deep object graphs that might cause performance issues.

Now that the logic is created to generate the proper mappings then we have to use it in a call to RegisterTypes:

IUnityContainer container = new UnityContainer();

container.RegisterTypes(
    AllClasses.FromLoadedAssemblies().Where(t => !t.IsGenericTypeDefinition),
    WithMappingsCustom.FromAbstractClass,
    WithName.TypeName,
    WithLifetime.PerResolve);
            
container.RegisterTypes(
    AllClasses.FromLoadedAssemblies().Where(t => t.IsGenericTypeDefinition),
    WithMappingsCustom.FromAbstractClass,
    WithName.Default,
    WithLifetime.PerResolve);

There are two calls to RegisterTypes: the first does non-generic types the second does generic types. The reason is that it’s assumed that because we are mapping abstract classes that there will be many mappings to concrete types so will use named mappings (by using WithName.TypeName). For the generic types, it’s assumed that there will just be one registration so the default (unnamed mapping) is sufficient.

It should be working but let’s check:

AbstractRepository testRepository =
    container.Resolve<AbstractRepository>(typeof(TestRepository).Name);
Debug.Assert(testRepository.GetType() == typeof(TestRepository));

testRepository =
    container.Resolve<AbstractRepository>(typeof(AnotherRepository).Name);
Debug.Assert(testRepository.GetType() == typeof(AnotherRepository));

AbstractBase testRepository2 =
    container.Resolve<AbstractBase>(typeof(TestRepository).Name);
Debug.Assert(testRepository2.GetType() == typeof(TestRepository));

AbstractRepository<string> stringRepository =
    container.Resolve<AbstractRepository<string>>();
Debug.Assert(stringRepository.GetType() == typeof(TestRepository<string>));

AbstractRepository<int> closedRepository =
    container.Resolve<TestRepositoryClosed>();
Debug.Assert(closedRepository.GetType() == typeof(TestRepositoryClosed));
Debug.Assert(typeof(AbstractBase<int>).IsAssignableFrom(closedRepository.GetType()));

So everything is working and we are done.

Well, we could be done. But there are more changes that we can do.

Unity provides a way to formalize registration logic by using the abstract RegistrationConvention class. This provides a common method of sharing registration logic.

So instead of using our static helper class the logic can be encapsulated by a RegistrationConvention using the helper method and some values from the original post:

public class AbstractClassRegistrationConvention : RegistrationConvention
{
    private static readonly IEnumerable<InjectionMember> EmptyInjectionMember
        = new InjectionMember[0];

    public override Func<Type, IEnumerable<Type>> GetFromTypes()
    {
        return (t) => WithMappingsCustom.FromAbstractClass(t);
    }

    public override Func<Type, IEnumerable<InjectionMember>> GetInjectionMembers()
    {
        return (t) => EmptyInjectionMember;
    }

    public override Func<Type, LifetimeManager> GetLifetimeManager()
    {
        return WithLifetime.PerResolve;
    }

    public override Func<Type, string> GetName()
    {
        return WithName.TypeName;
    }

    public override IEnumerable<Type> GetTypes()
    {
        return AllClasses.FromLoadedAssemblies()
            .Where(t => !t.IsGenericTypeDefinition);
    }
}

public class AbstractGenericClassRegistrationConvention
    : AbstractClassRegistrationConvention
{
    public override IEnumerable<Type> GetTypes()
    {
        return AllClasses.FromLoadedAssemblies()
            .Where(t => t.IsGenericTypeDefinition);
    }

    public override Func<Type, string> GetName()
    {
        return WithName.Default;
    }
}

All the registration logic is now hidden so that the registration code is incredibly simple looking:

IUnityContainer container = new UnityContainer();

var convention = new AbstractClassRegistrationConvention();
container.RegisterTypes(convention);

convention = new AbstractGenericClassRegistrationConvention();
container.RegisterTypes(convention);

In this post a method for registering abstract base classes from a concrete type was demonstrated as well as a how to formalize this logic into a RegistrationConvention.

Posted in Uncategorized | Tagged , , | Leave a comment

EnterpriseLibrary.Config for VS2013

EnterpriseLibrary.Config is a Visual Studio extension that launches the Enterprise Library Configuration Tool.  This is handy because it’s always a right click away without having to leave Visual Studio and locate the config tool and open the config tool and open the config file you want to edit.  Also, when combined with installing EntLib packages via NuGet, the tool automatically knows what application blocks can be configured.

Unfortunately, there is no official version that supports Visual Studio 2013.  So to fill the gap, I’ve created new extensions by updating the existing EntLib5 and EntLib6 extensions to both support VS2013.

Microsoft.Practices.EnterpriseLibrary.ConfigConsole.V5.VS2013.vsix

Microsoft.Practices.EnterpriseLibrary.ConfigConsole.V6.VS2013.vsix

Posted in Uncategorized | Tagged , , , | 1 Comment

Semantic Logging Application Block 2.0 Released

Version 2.0 of the Semantic Logging Application Block (SLAB) was recently released. There’s been a lot of internal refactoring including changes to make the block simpler (removing unnecessary conversions) and the NuGet packages more modular. Check out the Release Notes for the details on all the goodness.

Posted in .NET, Enterprise Library, Logging, SLAB | Leave a comment

Developer’s Guide to Microsoft Enterprise Library, 2nd Edition Released!

Developer’s Guide to Microsoft Enterprise Library, 2nd Edition Released!

The patterns & practices team has released the 2nd Edition of the Developer’s Guide to Microsoft Enterprise Library.  The guide covers Enterprise Library 6 including the new Semantic Logging Application Block. 

If you are using Enterprise Library or thinking about it this is an invaluable guide.

Posted in Uncategorized | Leave a comment

Hands-on Labs for Enterprise Library 6 Released!

Hands-on Labs for Enterprise Library 6 has been released.  The labs provide guided exercises (with before and after code) demonstrating how to use Enterprise Library/Unity.

Included are Labs dealing with:

  • Data Access
  • Exception Handling
  • Interception (Unity)
  • Logging
  • Semantic Logging
  • Transient Fault Handling
  • Unity
  • Validation

 

Posted in .NET, Enterprise Library | 3 Comments

Is Enterprise Library Outdated?

Over the last few days I’ve seen a few references to Enterprise Library being outdated or even retired. So in the spirit of a semi-rant I thought I would post some thoughts.

Enterprise Library 6 was just released within the last 2 months! So, it’s definitely still being developed. This release included a new application block, The Semantic Logging Application Block which makes use of some of the new .NET 4.5 features and some of the older blocks were retired. So news of its demise are exaggerated.

The blocks address common cross cutting concerns and provide a common approach that applications can use in these areas. Usually, the blocks also fill in an area of the framework that is missing or lacking in functionality.

For example, up until fairly recently there was no built-in general purpose caching functionality available in .NET (save System.Web.Caching). In earlier versions of Enterprise Library the Caching Application Block could fill this need. However, since caching is now built in the Caching Application Block has been removed from Enterprise Library 6. See On deprecation for a discussion of the philosophy involved. Same story with the old Configuration Application Block which disappeared when the .NET Framework added built-in custom configuration.

The Data Access Application Block is an example of older code that one may call “outdated”. There has certainly been many new data access technologies that have come out of Microsoft (some might say too many 🙂 ) with more advanced capabilities. However, the block is still a good wrapper over ADO.NET. If that is what you need/want then it is still a good option. Of course, it is not an ORM, was never intended to be an ORM (and almost certainlywill never be an ORM).

Enterprise Library is also quite extensible with a variety of extension points. In addition, if that is not sufficient it is open source with a permissive license making it easy to customize and tailor the blocks for specific scenarios.

Enterprise Library has formally been around for 8 years (and at least 10 if you include the precursor Application Blocks such as Data Access) but it’s still evolving and trying to make developers’ lives easier.

OK, that’s enough of my rambling.

Posted in .NET, Enterprise Library | Tagged , , | 5 Comments

Enterprise Library 6 Logging Performance

With the release of Enterprise Library 6, I thought I would take a look at the relative performance between logging in Enterprise Library 5 vs. Enterprise Library 6.

The Logging Application Block has had some internal implementation changes for version 6 (along with new features such as asynchronous logging added).  Version 6 also targets .NET 4.5 which itself has some performance improvements.

An admittedly artificial test was performed of creating a LogWriter and then logging to a flat file 100,000 times.  The exact same code and configuration was used for both tests and each test was run 5 times and the results averaged.

The results are in and Enterprise Library 6 averaged 1835 ms vs. an average of 2389 ms for Enterprise Library 5. That means that Enterprise Library 6 shaved 554 ms — about 23% — off of the Enterprise Library 5 time.

Here is the raw data:

EntLib 5 EntLib 6
Run 1 (ms) 2391 1787
Run 2 (ms) 2412 1809
Run 3 (ms) 2381 1919
Run 4 (ms) 2391 1864
Run 5 (ms) 2371 1796
Average (ms) 2389.2 1835

And here is the code and configuration:

    class Program
    {
        static void Main(string[] args)
        {
            LogWriter logWriter = new LogWriterFactory().Create();
            logWriter.Write("Init", "General");

            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();

            for (int i = 1; i <= 100000; i++)
            {
                logWriter.Write("Entry", "General");
            }

            stopWatch.Stop();

            Console.WriteLine("Elapsed Milliseconds:\t" + stopWatch.ElapsedMilliseconds);
        }
    }

<!--?xml version="1.0" encoding="utf-8" ?-->
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging" requirePermission="true" />
    </configSections>
    <loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
        <listeners>
            <add name="Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging"
                listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging"
                fileName="trace.log" formatter="Text Formatter" />
        </listeners>
        <formatters>
            <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging"
                template="Timestamp: {timestamp}{newline}
Message: {message}{newline}
Category: {category}{newline}
Priority: {priority}{newline}
EventId: {eventid}{newline}
Severity: {severity}{newline}
Title:{title}{newline}
Machine: {localMachine}{newline}
App Domain: {localAppDomain}{newline}
ProcessId: {localProcessId}{newline}
Process Name: {localProcessName}{newline}
Thread Name: {threadName}{newline}
Win32 ThreadId:{win32ThreadId}{newline}
Extended Properties: {dictionary({key} - {value}{newline})}"
                name="Text Formatter" />
        </formatters>
        <categorySources>
            <add switchValue="All" name="General">
                <listeners>
                    <add name="Flat File Trace Listener" />
                </listeners>
            </add>
        </categorySources>
        <specialSources>
            <allEvents switchValue="All" name="All Events" />
            <notProcessed switchValue="All" name="Unprocessed Category" />
            <errors switchValue="All" name="Logging Errors &amp; Warnings">
                <listeners>
                    <add name="Flat File Trace Listener" />
                </listeners>
            </errors>
        </specialSources>
    </loggingConfiguration>
</configuration>

Each test app was a console application built in release mode. EntLib 5 app targeted .NET Framework 4 Client Profile while EntLib 6 app targeted .NET Framework 4.5. The OS for both tests was Windows 7 Professional.

For the record the CPU was an Intel Core i5-2430M @2.40GHz with 6 GB RAM and a SanDisk 256GB SSD HDD (SDSSDHP-256G).

The purpose of the test was not the absolute metrics but the relative difference between version 5 and version 6. In this set of tests Enterprise Library 6 had a significant performance improvement over the previous version.

Posted in .NET, Enterprise Library | Tagged , | Leave a comment

Enterprise Library 6: Installation and VS2012 Configuration

This post will go through how to install Enterprise Library 6 binaries and configure Visual Studio 2012.

The easiest way to install Enterprise Library 6 is to use NuGet (see Installing NuGet for information on installing NuGet) .  Right-click on Add References and select “Manage NuGet Packages…”.  Then search for entlib6 and install the packages you wish.

However, in some situations you may wish to use alternative approaches.  For example download the binaries in order to explicitly manage versions or have a standard library location for developers etc.

Download and Install Enterprise Library

The first step is to download the binaries.  You can download the binaries EnterpriseLibrary6-binaries.exe from from http://www.microsoft.com/en-us/download/details.aspx?id=38789.

Next Run EnterpriseLibrary6-binaries.exe:

EntLib1

Select Yes (if you agree!).  Then browse for the folder to install the binaries into.  This can be any location you wish.  For this example I will use C:\EntLib\EntLib6.  This is one difference from previous releases.  In previous releases an installer would actually install Enterprise Library into Windows but with EntLib6 the files are extracted to the target folder.  The files will be unpacked and when done you should get a success message:

EntLib2

If we open up a command shell and browse to the location of unpacked files we will see the following:

EntLib3

If you’ve used Enterprise Library before you would probably notice that the actual assemblies have not been installed.  A quick look at the ReadMe file will let you know that you need to download the binaries using the supplied script, install-packages.ps1.

Run the script by typing: powershell -File .\install-packages.ps1

EntLib4

EntLib5

Type Y and hit <ENTER>.  You should receive message that the packages were successfully installed:

EntLib6

All assemblies are now in the current directory (e.g. C:\EntLib\EntLib6):

EntLib7

That completes the installation.

Assemblies can now be added as file references but how can we get good integration with Visual Studio 2012?

Visual 2012 Configuration

NuGet

Along with downloading the assemblies into the target folder the previous steps also installed the NuGet packages locally.  What can we do if we don’t want to be dependent on an internet connection to add Enterprise Library to our projects?  One way is to create a local package source for Enterprise Library.

To do this open up Package Manager Settings (TOOLS->Library Package Manager-> Package Manager Settings):

EntLib8

Next go to Package Manager->Package Sources and add a new entry for EntLib6.  Click Add, Enter a Name and a Source (where the NuGet packages were installed which in this example is C:\EntLib\EntLib6\.nuget\packages) and click Update:

EntLib9

Then click OK.

Now when opening Manage NuGet Packages

EntLib10

we can select the local EntLib6 Packages as the source of all Enterprise Library 6.  (“local” could also be on a shared network folder if desired.)

EntLib11

Using the above approach we can still use NuGet to manage our local Enterprise Library binaries.

Add Reference Configuration

But what if we don’t want to mess around with NuGet and we just want to have the Enterprise Library assemblies appear in the list of assemblies in Add Reference (old school!)?  To do this we can use the technique described in How to: Add or Remove References By Using the Add Reference Dialog Box.

The following is for Visual Studio 2012 64-bit version. As a privileged user, open up the Registry Editor (regedit) and browse to the appropriate .NET Version Key:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\<version>\AssemblyFoldersEx

On my machine this is:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.5.50709\AssemblyFoldersEx

Add a New Key for EntLib6 and set the default value to the location where Enterprise Library 6 was installed (C:\EntLib\EntLib6\ in this example):

EntLib12

Now when adding a reference in VS2012 we should Enterprise Library 6 assemblies in the Extension list:

EntLib13

Conclusion

Unfortunately, this post turned out to be very long.  The good news is that we’ve seen how to install Enterprise Library 6 and a few methods of configuring Visual Studio 2012 to easily use the blocks.

Also, note that we haven’t discussed installing Enterprise Library in the GAC.  If you wish to install in the GAC then you would have to manually install the desired assemblies in to the GAC (e.g. gacutil or drag the assemblies into GAC).

Posted in .NET, Enterprise Library | Tagged , | 8 Comments