Search code examples
wcfinversion-of-controlcastle-windsorcustom-attributeswcffacility

WCF Attribute injection using an IOC Container


Using ASP.NET MVC I am able to replace the FilterProvider as so

 var oldProvider = FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider);
 FilterProviders.Providers.Remove(oldProvider);
 FilterProviders.Providers.Add(new CustomFilterProvider(_container));

Using my own custom provider. It does not give me the ability to use a factory pattern to create the controller filter attributes but I do get the ability to use property injection to set dependencies the attributes may need using the container.

Is it possible to do something similar using WCF so that I can inject dependencies (property injection is fine) into my user defined classes that derive from Attribute that I use on my service methods (the services are created using IOC)?

I am using CastleWindsors WcfFacility, but a generalised solution (that applied to any container) would probably be a better answer.


Solution

  • One way to do this is to use the containers OnCreate method or similar and do something like the following at registration

      Container.Register(Component.For<IMyService>().ImplementedBy<MyService>().OnCreate(WireUpAttibutes).LifeStyle.Transient);
    

    then have the following methods

      private static void WireUpAttibutes<T>(IKernel kernel, T instance) {
         var attributes = instance.GetType().GetCustomAttributes(typeof(MyAttribute), false);
         foreach (var attribute in attributes) {
            WireUp(kernel, attribute.GetType(), attribute);
         }
      }
    
      private static void WireUp(IKernel kernel, Type type, object instance) {
         var properties = type.GetProperties().Where(p => p.CanWrite && p.PropertyType.IsPublic);
         foreach (var propertyInfo in properties.Where(propertyInfo => kernel.HasComponent(propertyInfo.PropertyType))) {
            propertyInfo.SetValue(instance, kernel.Resolve(propertyInfo.PropertyType), null);
         }
      }