2

I have a WCF service that will be called from a various clients.

Internally the WCF service uses an ISomething. There are multiple implementations of this interface and I need some clients to use one implementation and other clients to use a different implementation.

In addition, I am using Unity and an IoC container. I would typically set up a custom factory to allow the wcf service itself to be resolved along with its dependency graph, but if I have multiple implementations of a dependency, I do not think I can go with this approach and would have to resort to resolving the ISomething within the service (effectively using Unity as a service locator) which is not ideal.

So I need to work out

(1) how to specify which implementation of ISomething a client needs (eg. use a header, pass implementation string in each method, host multiple endpoints etc.)

(2) how Unity fits in?

1 Answer 1

2

One option is to write a Decorator that performs the selection for you:

public class RoutingSomething : ISomething
{
    private readonly ISomeContext ctx;
    private readonly ISomething s1;
    private readonly ISomething s2;
    private readonly ISomething s3;

    public RoutingSomething(ISomeContext ctx)
    {
        this.ctx = ctx;

        // An even better design would be to inject these too
        this.s1 = new BarSomething();
        this.s2 = new BazSomething();
        this.s3 = new QuxSomething();
    }

    // Assuming ISomething has a Foo method:
    public void Foo()
    {
        if(this.ctx.Bar())
        {
            this.s1.Foo();
            return;
        }
        if(this.ctx.Baz())
        {
            this.s2.Foo();
            return;
        }
        if(this.ctx.Qux())
        {
            this.s3.Foo();
            return;
        }
    }
}

You could generalize this so that ISomeContext is simply an Abstract Factory of ISomething. This then begins to turn into the general solution to varying dependencies based on run-time context.

You can now register RoutingSomething in Unity in addition to your other components. When the container resolves the service, it'll inject an instance of RoutingSomething into it.

Sign up to request clarification or add additional context in comments.

2 Comments

That is pretty nifty but I still need for the service to know which implementation the CLIENT wants to use. How do I pass this information so that it can be accessed early enough to be available when I resolve the service?
Is the service protected by any sort of authentication? If it is, you might be able to use the authenticated principal as a key to select the correct service. Otherwise, a custom header sounds like a reasonable option.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.