views:

63

answers:

1

I have an interface, for example ISomeService. ISomeService provides a common service, but the implementations may vary. As such, they will have different dependencies.

Consider:

interface ISomeService
{
     void DoSomething();
}

class SomeServiceA : ISomeService
{
     public SomeServiceA(DependencyOne one, DependencyTwo two)
     {
     }


     public void DoSomething()
     {
     }
}

class SomeServiceB : ISomeService
{
     public SomeServiceB(DependencyThree three)
     {
     }

     public void DoSomething()
     {
     }
}

Now, the reality is I can't just add a dependency to ISomeService to my controller and be done with it. I will need to choose an implementation of IService based on what a user tells me, and I may have to create multiple copies of the service they selected.

Perhaps I'd have a class that allows me to resolve an instance of the ISomeService I need, by type:

class SomeServiceProvider
{
    public T Get<T>()
        where T : ISomeService
    {
          // uh oh, this is starting to have a bad smell... do I call the container? that's no good
    }

}

So I could

class SomeController
{
     SomeServiceProvider ServiceProvider { get; set; }

     public SomeController(ServiceProvider provider)
     { ServiceProvider = provider; }

     public void SomeAction(string serviceName)
     {
          ISomeService someService;
          if (serviceName.Equals('SomeServiceA')) someService = ServiceProvider.Get<SomeServiceA>();
          else someService = ServiceProvider.Get<SomeServiceB>();
          someService.DoSomething();
     }

}

It seems that Autofac's delegate factory would not be appropriate here, and I'm not sure what to do otherwise (except use a service locator). Any recommendations?

+2  A: 

Is this what you need? Service types, names and keys

Services can be further identified using a service name. Using this technique, the Named() registration method replaces As().

builder.Register<OnlineState>().Named<IDeviceState>("online");

To retrieve a named service, the ResolveNamed() method is used:

var r = container.ResolveNamed<IDeviceState>("online");
adrift
I think the section **Resolving an Index** in your link will do what I want, although it's a little awkward that I have to write a component that requires a reference to Autofac itself. But, I suppose I can deal with that. Thanks!
HackedByChinese
I'd suggest creating a SomethingFactory that uses IIndex and implements ISomethingFactory, which you can then use in your controllers - best of both worlds! :) Types like IIndex are best kept to the infrastructure part of your application - where it interacts with the IoC container - rather than regular application components. Best of luck with it! Nick
Nicholas Blumhardt