11

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>();
        }
    }
Community
  • 1
  • 1
Blake Pettersson
  • 8,927
  • 3
  • 27
  • 36
  • 1
    I don't know what else to call it. If you want me to be specific a "wcf validator" in this case would be a custom implementation of a UserNamePasswordValidator. – Blake Pettersson Jul 27 '09 at 08:53
  • John. Why are you so cocky? I might be like that too if I had over 56,000 rep points, but you kind of come off as being condescending. These opinions are not only from this post, but from other responses and threads that you have been involved in where, in some cases, you come off brutal and mean. – SideFX Nov 01 '10 at 16:25
  • @SideFX: I have no idea what you mean? I just asked him what he meant by "WCF Validator". How is that being "cocky"? – John Saunders Nov 03 '10 at 20:12

2 Answers2

3

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
  • 4,493
  • 20
  • 19
  • 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 Jul 24 '09 at 09:58
  • Could you please give me code sample and exception details and i will try to help you. – Dzmitry Huba Jul 24 '09 at 10:36
  • Right, but you didn't answer what you mean by "WCF Validator". – John Saunders Jul 24 '09 at 13:51
  • 3
    @John Also, I believe that the Microsoft community got a bad rap because of attitudes like yours. Friends I've talked to compare the Java and Microsoft community and say that Microsoft folks comes off snobby and vitrolic. You should look to the light of evangelists such as Phil Haack and and Hanselman, who are trying real hard to recreate the image of the Microsoft community, which in my opinion, should breed free thinking individuals. What is wrong with the guy calling it a "WCF Validator". YOU KNOW WHAT HE MEANS. And I'm sure the term didn't cause the hard drive in your brain to crash. – SideFX Nov 01 '10 at 16:36
  • @SideFX: no, I didn't know what he meant. – John Saunders Nov 03 '10 at 20:13
  • @Dzmitry I am hosting my application in IIS and I am using Autofac as my IOC container. My custom validator class uses DI. Is there a way to register my custom class from app config? Im getting the same error as above "System.MissingMethodException: No parameterless constructor defined for this object." – ministrymason Sep 24 '12 at 14:49
  • I haven't used .NET for a while, but perhaps this link might be relevant: http://stackoverflow.com/a/6761284/89509 – Blake Pettersson Nov 26 '12 at 09:48
  • +1 for the passion of @SideFx. However, in my career, the people he describe tend to come more from Java than Microsoft. ;) – Samuel Jul 03 '15 at 10:27
2

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
  • 6,403
  • 1
  • 27
  • 26
  • I tend to do this when there's no other option available - leave the regular constructor, and provide a second parameterless constructor that calls the original using ServiceLocator'ed arguments – Alex Jun 04 '15 at 09:58