Exposing WCF service without .svc extension

I know, this is a weird requirement, but sometimes they appear in your backlog. The story is: as company XXX I want to expose a service based on WCF in IIS without having the .svc suffix in the address. I’m actually using Castle Windsor WCF Integration to resolve my service class with castle, and it turns out that exposing a service without using standard .svc files it is just a matter of configure routing. This line of code is configuring the route of a specific name to a wcf service

RouteTable.Routes.Add(
  new ServiceRoute("UiService", 
    new DefaultServiceHostFactory(IoC.GetContainer().Kernel), typeof(IUiService)));

This indicates to Asp.Net engine that the UiService address route actually maps to the DefaultServiceHostFactory of Castle and it will be solved by the implementation of a IUiService. Remember that you need to enable aspNetCompatibilityEnabled in your servicemodel section of web config and all the service should have the attribute

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

If you do not remember how to enable aspNetCompatibility it is just a setting in your web.config inside the ServiceModel section

    <serviceHostingEnvironment aspNetCompatibilityEnabled="True">

    </serviceHostingEnvironment>

Now your service is exposed as a simple url, ex: http://www.mysite.org/services/UiService

Gian Maria.

Making Castle and MEF happy togheter

If you use Mef to dynamically load handlers for your services (as described in this post), you will probably need to declare dependencies to various other software service. Since MEF is not born to handle dependencies, you will probably use other libraries for DI, Es. Castle.Windsor. Now the problem is “how can I make MEF and my IoC container living together happily with minimum effort?”. To keep everything simple you will need to understand typical scenario, you want to solve, a first problem you need to solve is “Mef imported classes should be able to declare dependencies on services defined in my primary IoC container engine§.

The simplest solution you can use is using MEF attributes to declare dependencies from other service with the ImportAttribute.

[Import]
public IXXXService PostProcessingService { get; set; }

This will instruct MEF that this service needs an instance of IXXXService to work properly, but I want to resolve it with my IoC system and not with MEF. To solve this problem you can use a cool feature of Mef and export IXXXService from a property of a simple helper class.

public class CastleToMefBridge
{
    [Export(typeof(IXXXService))]
    public IXXXService XXXService
    {
        get
        {
            return IoC.Resolve<IXXXService>();
        }
    }
public class CastleToMefBridge
{
    [Export(typeof(IXXXService))]
    public IXXXService XXXService
    {
        get
        {
            return IoC.Resolve();
        }
    }

This code will not export a complete class, but it marks the XXXService property as an Export of IXXXService, now whenever MEF will find an ImportAttribute for the IXXXService type it will call this property that internally simple use my primary IoC to resolve dependency.

When you use this technique you need to pay a lot of attention to the lifecycle of the dependencies, because if they are transient you will need to call Release in Castle container to avoid keeping a reference to it forever. Usually this problem is mitigated by the fact that all types exported by MEF are by default singleton, so even if they declare an Import of a type that has a transient lifetime with castle, you will never need a call to release because Mef Imported component will live for the entire duration of the application.

Gian Maria.

Moving between different IoC containers

I must admit that I always prefer castle Windsor over other IoC containers, but the main reason is that I’m really used to it and all its facilities. I know how to write facilities, and I know how it behave, this makes difficult for me moving to other Container because I usually need time to find how to do same stuff I do with castle with the new Toy.

Actually I’m using Unity sometimes and today I need to mimic the IStartable facility of Castle, because I need Start method to be called whenever the object gets registered, and stop called when the container is disposed. The very first tentative is this code.

public class StartableBuilderStrategy : BuilderStrategy
{
    public override void PostBuildUp(IBuilderContext context)
    {
        base.PostBuildUp(context);
        if (context.Existing is IStartable)
        {
            ((IStartable)context.Existing).Start();
        }
    }

    public override void PreTearDown(IBuilderContext context)
    {
        if (context.Existing is IStartable)
        {
            ((IStartable)context.Existing).Stop();
        }
        base.PreTearDown(context);
    }
}

This code seems to me legitimate to write, but I encounter a problem, when I dispose the container the PreTearDown method is not called. This happens because the PreTearDown method is called only when someone explicitly calls TearDown on the Unity container actually asking the container to teardown the object. Actually I do not like very much how unity track lifetime of object and I suggest you reading this post for a good introduction on the subject, but in my situation I only need these two feature for singleton object (ContainerControlledLifetimeManager).

  1. When the object get constructed I want its start method called
  2. When the container gets disposed I want the method stop called.
  3. Create the object (and call start) when the object is registered in the container

With unity you can solve these two point with really few lines of code, first of all if you want a method to be called when the object gets constructed you can both call the method in the constructor (if any) or you can use a specific attribute

[InjectionMethod]
public void Start()
{

The InjectionMethod attribute gets called after the object is constructed without the need of any other configuration, for the point 2 simply implement IDisposable and call Stop in the Dispose Method. This is still not the very same behavior of Castle Startable facility, because it starts the object immediately upon its registration. The purpose of Startable Facility is the ability to being able to start objects during registration and not when they are first used to resolve a dependency. In unity you can mimic this adding this extension

public class StartableExtension : UnityContainerExtension
{
    protected override void Initialize()
    {
        Context.Registering += Context_Registering;
    }

    void  Context_Registering(object sender, RegisterEventArgs e)
    {
        if (typeof(IStartable).IsAssignableFrom(e.TypeTo))
        {
            Container.Resolve(e.TypeFrom);
        }
    }
}

public interface IStartable
{

}

As you can see the IStartable interface does not define any method, because actually Start() and Stop() should be called with the InjectionMethodAttribute and IDisposable, but it is needed only to automatically create an instance of the type during registration.

Gian Maria.

Managing remote logging with Log4net and WCF

I’ve applications that can work in two distinct configuration, they are based on WPF and MVVM, where the VM communicates with the Domain / Business Logic through services like IXxxxService. All View Models depends from one or more services and thanks to Castle I can decide with configuration file which concrete class to use for each service.

When the software is used internally, it has direct access to the Database, so I configure castle to use the concrete class of the various services, but when the software is deployed to external users,  who have no access to the intranet, all communication is done through WCF. This is done transparently because I have a facility that resolve the various IXxxxService with WCF Proxy classes.

All software logs a lot, to be able to diagnostic errors as soon as possible, and I have a IManagement service that has a method dedicated to logging.

   1: [OperationContract(IsOneWay=true, ProtectionLevel=ProtectionLevel.EncryptAndSign)]

   2: void Log(LogDto log);

The implementation of this method is really really simple.

   1: public void Log(Dto.LogDto log)

   2: {

   3:     log.Log(Logger);

   4: }

The LogDto has a method Log, that is able to log everything to an ILogger Castle standard logger that in turns uses Log4Net, so remote program can send log through WCF.

My problem is that the various ViewModels are using classes from a shared library and those classes uses Log4Net internally to log stuff. If the software is deployed in internal network I have no problem because I can redirect logging in a log database, but when the software is used by external user how can I send all those log to the server?

The solution is simple I need to create a custom Log4Net appender to intercept Log4Net logs and redirect them to IManagementService.

   1: class ManagementLogAppender : AppenderSkeleton

   2:  {

   3:      private IManagementService _managementService;

   4:  

   5:  

   6:      public ManagementLogAppender(IManagementService managementService)

   7:      {

   8:          _managementService = managementService;

   9:      }

  10:  

  11:      protected override void Append(log4net.Core.LoggingEvent loggingEvent)

  12:      {

  13:          LogDto logDto = new LogDto();

  14:          logDto.Message = loggingEvent.MessageObject.ToString();

  15:          if (loggingEvent.ExceptionObject != null)

  16:          {

  17:              logDto.FullExceptionData = loggingEvent.ExceptionObject.ToString();

  18:          }

  19:          logDto.LoggerName = loggingEvent.LoggerName;

  20:          _managementService.Log(logDto);

  21:      }

  22:  }

This appender simply send the log to the IManagementService so I have a centralized point where all the remote logging takes place. Since I have more than one custom appender, I usually register all of them inside Castle Windsor Configuration and add all registered one with this simple snippet of code, that is run from the bootstrapper.

   1: var allAppender = IoC.ResolveAll<IAppender>();

   2: Hierarchy repository = LogManager.GetRepository() as Hierarchy;

   3: foreach (IAppender appender in allAppender)

   4: {

   5:     repository.Root.AddAppender(appender);

   6: }

   7: repository.RaiseConfigurationChanged(EventArgs.Empty);

This permits me to have appenders that can declare dependencies, like the ManagementLogAppender that is depending from IManagementService. Thanks to the same facility I can use the concrete class in intranet (direct use of log4net) or the dynamic generated proxy that send log through WCF.

Gian Maria.

AoP with castle part 4–Adding AoP to service oriented App

Previous Parts of the series

Part 1 – The basic of interception
Part 2 – Selecting Methods to intercept
Part 3 – The first interceptor

AOP works great if you have clear interfaces where you want to put some standard and shared logic, and a Service Oriented Application falls in this category. A service is just a bunch of methods that will share some common behavior like: Validation, logging, Security etc etc, so it is a good strategy to create interceptors for each one of this behavior and associate them to service classes. The good point is that Castle has a dedicated facility to integrate with WCF, that basically is able to resolve WCF server classes with castle. Setting up such a facility is really simple, and you can follow the instruction found on castle’s site.

Surely the first aspect you can add to a Service is the ability to log every call (seen in previous post), but you can also centralize some other operations such as: Exception management or NHibernate session handling.

Validation is another operations that benefit from being applied with AOP. In SOA scenario, services will usually accepts dto objects containing all data needed to accomplish a certain operation. Dto are used because services usually exposes a coarse grained interface to limit the number of calls needed to accomplish a business operation. This is because each call is usually made across a network and latency forces you to limit number of calls, this lead to a common pattern where a business operation is implemented with a single call accepting a dedicated dto. In our example, to create a new album we need to pass an Album object (in real scenario this object will have a list of songs). It is not a real dto because it is a Domain Object, but for this simple example think that it is a dto J, I’ve decorated entity properties with validation attributes.

   1: [DataMember]

   2: [Required("La proprietà Titolo è richiesta")]

   3: [RangeLength("Il titolo deve essere compreso tra 1 e 50 caratteri", 1, 50)]

   4: public virtual string Title { get; set; }

   5:  

   6: [Required("La proprietà Autore è richiesta")]

   7: [RangeLength("L'autore deve essere compreso tra 1 e 50 caratteri", 1, 50)]

   8: [DataMember]

   9: public virtual string Author { get; set; }

Those attributes are used by a validation library that is able to take an object as input and tell us if it is valid or not. Creating a validation aspect on this structure is straightforward because you can simply validate all objects that are not primitive one, or you can make all of your dto implement a marker interface, or you can use convention over configuration. The important concept is that a service call accepts one or more dto and each one support validation.

   1: public class ValidatorAspect : IInterceptor

   2: {

   3:     #region IInterceptor Members

   4:  

   5:     private DotNetMarche.Validator.Core.Validator validator = new Validator();

   6:  

   7:     public void Intercept(IInvocation invocation)

   8:     {

   9:         foreach (object argument in invocation.Arguments)

  10:         {

  11:             if (!argument.GetType().IsPrimitive) validator.CheckObject(argument);

  12:         }

  13:         invocation.Proceed();

  14:     }

  15:  

  16:     #endregion

  17: }

Method CheckObject() takes an object as argument, and raise a ValidationException if the object does not satisfy some validation rule. With this simple interceptor I’m sure that each call with invalid dto will throw an exception bringing me two distinct advantages: the first is that no invalid object will ever reach a service method and the other one is that the exception raised carries validation errors, so the client is able to understand why the call is failed. Suppose that the Album.Name is a required property, without validation here is the exception returned from a call with invalid arguments.

not-null property references a null or transient valueMusicStore.Entities.Album.Title

Server stack trace: at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter) at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)Now we have a service that when called with an invalid data will return some useful exception that tells us what exactely is the error.

Clearly this a NHibernate exception and the caller probably does not know anything about NH to understand why the call failed. Moreover it is not a good strategy to let all exceptions flow to caller, especially for security reason.

Now activate validator interceptor and look at what is happening when you invoke the SaveAlbum()with an empty dto: now a ValidationException is raised and the message is.

Title property length should be in range 1-50

Title property is required.

Author property is required.

Author property length should be in range 1-50

This is a really clear exception that can be used from the client to understand why the call failed. Now the next step is send back exception data in a way that is more WCF compliant, this is needed because the above examples where run with this configuration

   1: includeExceptionDetailInFaults="true"

this is a bad practice, because exceptions should not flow to the caller, but if you set this value to false, when an exception occurs on the server, the client gets

The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults ….

WCF has a specific technique to send back exception data to the caller in a Service Oriented way, you should specify with an attribute witch object will carry exception data to the caller, so whenever an exception occurs, the caller will receive a valid response object with data.

   1: [OperationContract, FaultContract(typeof(FaultDetail))]

   2: int Save(Album album);

As you can see, this declaration informs the client that in case of fault, service will return failure details in an object of type FaultDetail.

image

When an exception happens, server code should throw a very specific type of exceptions of type FaultException with the type of exception data as Type parameter, as showed with this code:

   1: throw new FaultException<FaultDetail>(

Thanks to AOP we can wrap every exception of the service and create specific data to be sent back to the client, categorizing types of error. Here is the code.

   1: public void Intercept(IInvocation invocation)

   2: {

   3:     try

   4:     {

   5:         invocation.Proceed();

   6:     }

   7:     catch (FaultException<FaultDetail>)

   8:     {

   9:         throw;

  10:     }

  11:     catch (ValidationException vex)

  12:     {

  13:         throw new FaultException<FaultDetail>(new FaultDetail(vex), "Validation Failed");

  14:     }

  15:     catch (Exception ex)

  16:     {

  17:         Logger.Error("Intercepted generic exception on service call", ex);

  18:         throw new FaultException<FaultDetail>(

  19:             new FaultDetail(ex), new FaultReason(ex.Message));

  20:     }

  21: }

As you can see, if the calls throws a FaultException<FaultDetail> we can simply rethrow (someone else in the stack already packed a correct WCF exception message), but if a validation exception occurs we should pack all validation exception in a FaultDetail object and throw back to the caller. Finally, for every generic exception we can simply pack exception information in FaultDetail object and tells to caller that something gone wrong.

Another interesting interceptor is used to manage the unit of work for single WCF call. For each call it simply check if a session was already created for that call, if not, it creates one and begin a transaction. It catch also all exception and if an exception occurs, it simply rollback the transaction and rethrow.

The advantage of using AoP is the ability to inject common logic in service pipeline to handle common aspect: validation, session management and error handing in a unique and common position.

Alk.