views:

396

answers:

2

Following up on using dependency injection for WCF services, is there any way of using DI for WCF validators, so that one could do this:

public class DIValidator : UserNamePasswordValidator
{
    private readonly IService service;

    [Inject]
    public DIValidator(IService service)
    {
        this.service = service;
    }

    public override void Validate(string userName, string password)
    {
        service.Login(userName, password);
    }
}

EDIT - I tried to apply Dzmitry's advice to my custom behaviour extension, since my validator is defined in app.config. Sadly I get a MethodMissingException, since wcf wants my validator to have a default constructor:

System.MissingMethodException: No default constructor has been defined for this object.

at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck)

Here is my behavior class:

    public class DependencyInjectionServiceBehavior : BehaviorExtensionElement, IServiceBehavior
    {
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            serviceHostBase.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = DISupport.Kernel.Get<IService>();
        }
    }
A: 

I know this is not the solution you're looking for, but I would create a default constructor that would get IService from your IoC container (service locator instead of DI). Not the nicest way to do this, but the simplest I can think of.

Edit: of course you could leave the constructor that allows you to inject the dependency, if you need to mock the IService for testing or any other purpouse.

maciejkow
+1  A: 

In general custom validator is assigned programmatically (there is also possibility to do so from config file) something like this and it is done just before service host is opened and basically this is also the time you create your DI container instance that will be further used to service instances through instance provider:

serviceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new LocalUserNamePasswordValidator();

You can as well use DI container to create your custom validator as well.

serviceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = unityContainer.Resolve<UserNamePasswordValidator>();
Dzmitry Huba
Cool, is there any way of assigning the validator type in app.config and instantiating the validator type from a IServiceBehaviour instance? I tried setting the CustomUserNamePasswordValidator from my custom behaviour class but I get a runtime exception when I start up my WCF service.
Blake Pettersson
Could you please give me code sample and exception details and i will try to help you.
Dzmitry Huba
Okay now I've edited my question.
Blake Pettersson
Right, but you didn't answer what you mean by "WCF Validator".
John Saunders