Showing posts with label Castle. Show all posts
Showing posts with label Castle. Show all posts

Friday, November 9, 2012

Adding custom WCF endpoint behavior in client code

Endpoint behaviors are used to customize the runtime behavior of WCF clients. It's very useful, for example, if we want to send some special information to WCF service with each call from client.

Suppose, we have ASP.NET application and we need to send current user identity with every call to our IPersonalService.

First of all, we need to configure our WCF client. We use Castle Windsor WCF Facility to do this. In Application_Start handler of Global.asax we need to create WindsorContainer, add WcfFacility, and register our IPersonalService with custom SecureEndpointBehavior:

 Container = new WindsorContainer();  
 Container.AddFacility<WcfFacility>();  
 var personalServiceUrl = ConfigurationManager.AppSettings["PersonalServiceUrl"];  
 Container.Register(Component.For<IPersonalService>().AsWcfClient(WcfEndpoint.BoundTo(new BasicHttpBinding()).At(personalServiceUrl).AddExtensions(new SecureEndpointBehavior())));  

To create desired endpoint behavior we need to implement actually endpoint behavior and message inspector.

Example of endpoint behavior class:
 public class SecureEndpointBehavior : BehaviorExtensionElement ,IEndpointBehavior  
   {  
     public void Validate(ServiceEndpoint endpoint)  
     {  
     }  
     public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)  
     {  
     }  
     public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)  
     {  
     }  
     public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)  
     {  
       clientRuntime.MessageInspectors.Add(new SecureMessageInspector());  
     }  
     protected override object CreateBehavior()  
     {  
       return new SecureEndpointBehavior();  
     }  
     public override Type BehaviorType  
     {  
       get { return typeof(SecureEndpointBehavior); }  
     }  
   }  

Example of message inspector class:
 public class SecureMessageInspector : IClientMessageInspector  
   {          
     public object BeforeSendRequest(ref Message request, IClientChannel channel)  
     {        
       var siteUser = DependencyResolver.Current.GetService<ISiteUser>();  
       var header = new MessageHeader<Guid>(siteUser.UserId);  
       var untypedHeader = header.GetUntypedHeader("UserToken", "MyProject");  
       request.Headers.Add(untypedHeader);        
       return request;  
     }  
     [DebuggerStepThrough]  
     public void AfterReceiveReply(ref Message reply, object correlationState)  
     {  
     }  
   }  

As you can see, SecureEndpointBehavior class just adds SecureMessageInspector instance to list of run-time message inspectors. Our SecureMessageInspector is very simple: it just creates MessageHeader, puts siteUser.UserId into, and adds this header to the list of headers.

Now, on IPersonalService side you can retrieve user id under which the call was made to the service. In IPersonalService implementation, you can use the following command to retrieve user id:
 var userId = OperationContext.Current.IncomingMessageHeaders.GetHeader<Guid>("UserToken", "MyProject");  

Tuesday, November 6, 2012

Installing WCF-client using Castle Wcf Facility

Let's say we want to consume WCF-service in our ASP.NET MVC application. We try to keep clean design, and we want to inject our dependent WCF service, say, in our MVC Controller.

For example:
 public class MyController : Controller  
 {  
   private readonly IAnonymousService _anonymousService;  
   public MyController(IAnonymousService anonymousService)  
   {  
    _anonymousService = anonymousService;  
   }  
 }  

To accomplish this we need new version of Castle Windsor container. You need to create WindsorContainer, add Castle WCFWacility, and then register your service.

It may looks like this(in your Global.asax Application_Start handler):
 Container = new WindsorContainer();  
 Container.AddFacility<WcfFacility>();  
 var anonumousServiceUrl = ConfigurationManager.AppSettings["AnonymousServiceUrl"];  
 Container.Register(Component.For<IAnonymousService>().AsWcfClient(WcfEndpointBoundTo(new BasicHttpBinding()).At(anonumousServiceUrl)));  

Friday, October 26, 2012

Writing custom Windsor Controller Factory in ASP.NET MVC

Let's say we use Windsor IoC container in our ASP.NET MVC3 application. We registered some dependencies in Global.asax bootstrapper and now we need somehow to resolve them in our controller.

Of course we can do this:
 public class MyController : BaseController  
 {   
   private IFoo _dependency;   
   public MyController()  
   {  
    _dependency = Container.Resolve<IFoo>();   
   }  
   public ActionResult Index()  
   {   
    _dependency.DoSomething(); 
     ... 
   }  
 }  

But it is not good solution, because now we have dependency on IoC container itself in our controller. Besides, using any forms of Service Locator is a bad design practice.

More elegant solution is to write custom Controller Factory(in our case it is Windsor Controller Factory):
 public class WindsorControllerFactory : DefaultControllerFactory  
 {  
   private readonly IKernel _kernel;  
   public WindsorControllerFactory(IKernel kernel)  
   {  
    _kernel = kernel;  
   }  
   public override void ReleaseController(IController controller)  
   {  
    _kernel.ReleaseComponent(controller);  
   }  
   protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)  
   {  
    if (controllerType == null)  
    {  
      throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));  
    }  
    var controller = (Controller)_kernel.Resolve(controllerType);      
    return controller;  
   }  
 }  

And then to register this factory as default Controller Factory in our MVC application in Global.asax:
 Container = new WindsorContainer();  
 ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container.Kernel));  

Now we can do elegant dependency injections in our controller's constructor without references on specific IoC(in our case it's Castle Windsor):
 public class MyController : BaseController  
 {  
   private IFoo _dependency;  
   public MyController(IFoo dependency)  
   {  
    _dependency = dependency;  
   }  
   public ActionResult Index()  
   {  
    _dependency.DoSomething();
     ...
   }  
 }  

Thursday, October 18, 2012

Dependency injection in ASP.NET MVC 3 validation attributes

In previous article(Dependency injection in ASP.NET MVC 3 action filters) we have seen how to inject dependencies in MVC Action Filters. Now let's try to inject dependency in Validation attribute. Validation attributes is used in MVC Model Validation. There are many useful built-in attributes, but often you need to write your own.

Let's imagine that we need attribute that validate that user's login(typed in registration form) is not occupied. So we write custom attribute:
 public class LoginExistanceValidatorAttribute : ValidationAttribute  
 {  
   public IRegistrator Registrator { get ; set ; }  
   public override bool IsValid(object value)  
   {  
      var valueStr = value as string;  
      if (string.IsNullOrEmpty(valueStr))  
       return false;  
      return Registrator.CheckLoginExistance(valueStr);  
    }  
 }  

Our attribute needs IRegistrator dependency to be injected. So, how to inject it? We have problem like one than we have discussed in previous article with Action Filters. And we have similar solution(as before, we use Castle Windsor IoC container):
 var container = new WindsorContainer();   
 container.Register(Component.For<ModelValidator>().ImplementedBy<WindsorModelValidator>().LifeStyle.Transient);   
 DataAnnotationsModelValidatorProvider.RegisterDefaultAdapterFactory((metadata, context, attribute) => container.Resolve<ModelValidator>(new { metadata, context, attribute }));  

All we need is to write custom Model Validator WindsorModelValidator that will inject dependencies in Validation attribute at some point. Example:
 public class WindsorModelValidator : DataAnnotationsModelValidator  
 {  
   public IWindsorContainer Container { get ; set ; }  
   public WindsorModelValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute): base(metadata, context, attribute)
   {  
   }  
   public override IEnumerable<ModelValidationResult> Validate(object container)  
   {  
     // inject the services from the container that  
     // the Validation attribute requires  
     Container.Kernel.InjectProperties(Attribute);  
     ValidationContext context = CreateValidationContext(container);  
     ValidationResult result = Attribute.GetValidationResult(Metadata.Model, context);  
     if (result != ValidationResult.Success)  
     {  
       yield return new ModelValidationResult  
       {  
         Message = result.ErrorMessage  
       };  
     }  
   }  
   protected virtual ValidationContext CreateValidationContext(object container)  
   {  
     var context = new ValidationContext(container ?? Metadata.Model, new WindsorServiceProvider(Container), null );  
     context.DisplayName = Metadata.GetDisplayName();  
     return context;  
    }  
 }  

All magic is in this line:
 Container.Kernel.InjectProperties(Attribute);  

We again use this extension method to inject dependencies in object. You can view code of this method in previous article about Action filters.

Wednesday, October 17, 2012

Dependency injection in ASP.NET MVC 3 action filters

So far it's not easy task to inject dependencies in MVC 3 action filters.

For example, we have action filter attribute that performs redirection to Login page if user is not authorized:
 public class AuthorizeAttribute : ActionFilterAttribute  
 {  
   public ISiteUser SiteUser { get; set; }   
   public override void OnActionExecuting( ActionExecutingContext filterContext)  
   {  
     if (!SiteUser.IsAuthenticated)  
     {  
       var urlHelper = new UrlHelper(HttpContext .Current.Request.RequestContext);  
       if (urlHelper.RequestContext.HttpContext.Request.Url != null)  
       {  
        filterContext.Result = new RedirectResult(urlHelper.Action("Login" , "Authentication" , new { ReturnUrl = urlHelper.RequestContext.HttpContext.Request.Url.PathAndQuery }));   
       }   
     }  
   }   
 }  

This action filter has dependency ISiteUser. So, how to inject concrete implementation of SiteUser there? It is good design practice to inject dependencies in constructor. But at this point we do not control moment when this attribute is created and we do not have any way
to catch this moment.

What we can to do is to write custom ActionInvoker(using Castle Windsor IoC container, for example) and to step in process of controller action invocation:
 public class WindsorActionInvoker : ControllerActionInvoker  
 {  
   private readonly IKernel _kernel;  
   public WindsorActionInvoker(IKernel kernel)  
   {  
     _kernel = kernel;  
   }  
   protected override ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList<IActionFilter > filters, ActionDescriptor actionDescriptor, IDictionary<string , object > parameters)  
   {  
     foreach (IActionFilter actionFilter in filters)  
     {  
      _kernel.InjectProperties(actionFilter);  
     }  
     return base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters);  
   }  
 }  

As you can see, we iterate through controller action filters and call InjectProperties extension method which magically performs dependency injections.

Let's look at this method:
 public static class WindsorExtensions  
 {  
   public static void InjectProperties(this IKernel kernel, object target)  
   {  
     var type = target.GetType();  
     foreach (var property in type.GetProperties( BindingFlags.Public | BindingFlags.Instance))  
     {  
      if (property.CanWrite && kernel.HasComponent(property.PropertyType))  
      {  
        var value = kernel.Resolve(property.PropertyType);  
        try  
        {  
          property.SetValue(target, value, null);  
        }  
        catch ( Exception ex)  
        {  
          var message = string.Format("Can't set property {0} on type {1}", property.Name, type.FullName);  
          throw new InvalidOperationException(message, ex);  
        }  
      }  
     }  
   }  
 }  

Now all the magic has gone without a trace. We simply iterate through properties of Action Filter and try to resolve them using Castle Windsor kernel. Of course this dependencies should be registered before. Also we need to setup WindsorActionInvoker as default ActionInvoker in our Web Application:
 var container = new WindsorContainer();  
 DependencyResolver.SetResolver(new WindsorDependencyResolver(container.Kernel));  
 container.Register(Component.For<ISiteUser>().ImplementedBy<SiteUser>());  
 container.Register(Component.For<IActionInvoker>().ImplementedBy<WindsorActionInvoker>().DependsOn(Property.ForKey( "kernel").Eq(container.Kernel)).LifeStyle.Transient);  

One more important point here is to setup custom WindsorDependencyResolver. This class will be used to resolve dependencies instead of default MVC dependency resolver(which actually just uses Activator.CreateInstance method). Our resolver looks like this:
 public class WindsorDependencyResolver : System.Web.Mvc.IDependencyResolver  
 {  
   private readonly IKernel _kernel;  
   public WindsorDependencyResolver(IKernel kernel)  
   {  
     _kernel = kernel;  
   }  
   public object GetService(Type serviceType)  
   {  
    return _kernel.HasComponent(serviceType) ? _kernel.Resolve(serviceType) : null ;  
   }  
   public IEnumerable<object > GetServices(Type serviceType)  
   {  
     return _kernel.HasComponent(serviceType) ? _kernel.ResolveAll(serviceType).Cast<object >() : new object [] { };  
   }  
 }  

Monday, October 15, 2012

How to remove component in Castle Windsor 3.0?

Say we have registered component in Castle Windsor:
 Container.Register(Component.For<IRegistrator>().ImplementedBy<TestRegistratorWhichReturnsGoodResult>());  

Sometimes in Unit tests i need to remove registered component from Castle Windsor and to register new one. Prior to 3.0 version we can do this:
 Container.Kernel.RemoveComponent(typeof(TestRegistratorWhichReturnsGoodResult).FullName);  
 Container.Register(Component.For<IRegistrator>().ImplementedBy<TestRegistratorWhichReturnsBadResult>());  

Аfter version 3.0 breaking changes we can't do this, because there is no RemoveComponent method in version 3.0.
But we can use the following approach:
  class RegistrationHandlerSelector :IHandlerSelector  
       {  
         public static bool UseBadResultRegistrator { private get; set; }  
         public bool HasOpinionAbout(string key, Type service)  
         {  
           return service == typeof(IRegistrator);            
         }  
         public IHandler SelectHandler(string key, Type service, IHandler[] handlers)  
         {  
           return handlers.First(x => UseBadResultRegistrator ? x.ComponentModel.Implementation == typeof (TestRegistratorWhichReturnsBadResult ) :  
                                      x.ComponentModel.Implementation == typeof (TestRegistratorWhichReturnsGoodResult ));                      
         }  
       }  

 Container.Register(Component.For<IRegistrator>().ImplementedBy<TestRegistratorWhichReturnsGoodResult>());  
 Container.Register(Component.For<IRegistrator>().ImplementedBy<TestRegistratorWhichReturnsBadResult>());  
 Container.Kernel.AddHandlerSelector(new RegistrationHandlerSelector());  

Now we can use RegistrationHandlerSelector.UseBadResultRegistrator field to choose which component to use.