Restoring NuGet Packages and gitignore

Some time earlier, I posted about “Restoring NuGet Packages for External Dependencies” to restore dependencies when building solution and this way you don’t have to commit “packages” folder.
Just a short note: If you are working with Git and have enabled restoring NuGet packages automatically then perhaps it would be helpful to add “packages/” to .gitignore file as you don’t want to commit the packages folder.
This is also been handled in latest VisualStudio.gitignore sample available at github/gitignore. By default the “packages/” is commented so don’t forget to uncomment the line (see line# 98).

 

Restoring NuGet Packages for External Dependencies

NuGet is an excellent visual studio extension and answer to dependency management in .NET. It makes super easy to manage third party libraries. If are working on .NET and have not noticed NuGet, you are missing something very useful, read about NuGet here.
If you have been working on Java platform then this is something similar to Maven dependency management 
In early days… developers used to commit third party libraries (.dlls) into source control, those who don’t tend to get part of GAC. So we have seen developers maintaining folders like Lib, External Libraries etc. as part of repositories or branches into source control. This approach is easy but have it’s own limitation such as version management and manual maintenance etc.
Then comes the NuGet Package Manager to resolve dependencies. It’s has benefit of integration with Visual Studio and manages packages over just libraries (dlls). It creates a “packages” folder to download all external libraries and their dependent libraries along with version management.

NuGet Package Manager
With that developers started committing “packages” folder into source control to share external dependencies across team or contributors and that is fine but over time this would make distributed versioning control systems like Git to grow significantly large due binaries.

Restoring Packages Automatically

With NuGet 2.0, now you don’t need to commit “packages” folder and let NuGet download and restore missing packages when you build solution
For NuGet to do this, you need to take few steps.
1) Check “Allow NuGet to download missing packages during build” in Tools -> Options -> Package Manager
2) Enable NuGet Package Restore
That will do the needful, it would create a nuget folder as part of your solution file and will now automatically restores the missing libraries. What happens is that at the time of build, NuGet reads the packages.config file, identify the missing ones and download the missing packages with mentioned version from NuGet gallery.
This way you don’t have to commit your “packages” file into source control and yet easily maintain dependencies.
Have you tried NuGet Package Manager, dear reader?

Configuring ELMAH with WCF using NuGet

I am sure most of you have used Error Logging Module and Handlers (ELMAH) for ASP.NET. ELMAH is one great open source project and real blessings for ASP.NET developers. If you don’t know about it, It’s a MUST SEE tool and in that case I would recommend you to read out Scott Ha introductory blog post on ELMAH.

BUT, in this post we are going to see how to configure ELMAH to work with WCF services because if you do that in a typical way then ELMAH is probably not going to work as expected and it won’t show you any unhandled exception.

So let’s get started!

ElmahWithWcfSolution

I have created a new WCF Application project ElmahWithWcf containing one contract IDemoService and service implementation class DemoService.

To add ELMAH, you can either download it from project host site and configure it or you can simply use NuGet to download and automatically install/configure ELMAH.

NuGet is a Visual Studio extension that makes it easy to install and update open source libraries and tools in Visual Studio. Perhaps it really does simplify the life of developer when it comes to configure third party open source libraries. If you haven’t used NuGet, I would strongly encourage you to install it from Visual Studio Extension Manager (Tools –> Extension Manager). It’s free. You can also read NuGet documentation on CodePlex.com for further help or ping me back.

Once you have installed it, you can Add/Configure ELMAH via “Add Library Package Reference” in context menu of references folder.

In Add Library Package Reference, search elmah in online packages and click install, which will automatically download the required assemblies and configure entries in web.config as well. Isn’t it cool?

Add Library Package Reference

Just in case if you don’t believe, with NuGet you get all the config entries automatically!!!

Config Entries by NuGet

With this ELMAH is now configured as you would typically do in ASP.NET web application, however, in contrast to ASP.NET app, it won’t log any unhandled exception that is raised in WCF service. For this, to work correctly, you need to create custom Error Handler implementing IErrorHandler as demonstrated in code snippet below:

public class ElmahErrorHandler: IErrorHandler 
{
    #region IErrorHandler Members
    
    public bool HandleError(Exception error) 
    {
        return false;
    }
    public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    {
        if (error == null) 
        {
            return;
        }
   
        if (HttpContext.Current == null) 
        {
            return;
        }
   
        Elmah.ErrorSignal.FromCurrentContext().Raise(error);
    }
  
    #endregion
 }
 
 //Further in addition to that, you need to create a Service Behavior Attribute implementing Attribute and IServiceBehavior 

  public class ServiceErrorBehaviorAttribute: Attribute, IServiceBehavior 
  {
    private readonly Type errorHandlerType;
    public ServiceErrorBehaviorAttribute(Type errorHandlerType) 
    {
        this.errorHandlerType = errorHandlerType;
    }
    
    #region IServiceBehavior Members 
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection < ServiceEndpoint > endpoints, BindingParameterCollection bindingParameters) 
    {
    }
    
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    {
        IErrorHandler errorHandler;
        errorHandler = Activator.CreateInstance(errorHandlerType) as IErrorHandler;
        if (errorHandler != null) 
        {
            foreach(ChannelDispatcherBase dispatcher in serviceHostBase.ChannelDispatchers) 
            {
                ChannelDispatcher cd = dispatcher as ChannelDispatcher;
                cd.ErrorHandlers.Add(errorHandler);
            }
        }
    } 
  
    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    {    
    }
    
    #endregion
 } 
 
 //And finally you need to apply the custom attribute on your service implementation class   
 [ServiceErrorBehavior(typeof(ElmahErrorHandler))]
 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
 public class DemoService: IDemoService 
 {
     #region IDemoService Members 
     public string GetData(int value) 
     {
        throw new Exception("TEST");
        return string.Format("You entered: {0}", value);
    }
    
    #endregion
 }

That is all you need to do for ELMAH to work with WCF.

 

At this point, ELMAH must show all unhandled exception in log file. For example, line number 9 throws an exception with message “Test”. If we invoke the service method, the ELMAH should log this exception. The log file can be browsed at http://ServerPath/elmah.axd

In fact, ELMAH is so convenient that we decided not to use Enterprise Library Logging Block and utilized ELMAH to log even handled exception as well (Yes another reason was timelines as well).

Did I hear How? Well, in that case you simply need to manually add one line in catch block.

image

This will inform/raise about the exception to ELMAH and so it will log the handled exception as well.

Hope this Helps!

In case of any feedback/experience, please do share…

Happy Coding!