在Autofac中实现通用服务工厂或提供程序

时间:2010-09-21 23:59:22

标签: c# dependency-injection factory provider autofac

我有一个界面,例如ISomeServiceISomeService提供了一项通用服务,但实现可能会有所不同。因此,它们将具有不同的依赖性。

考虑:

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()
     {
     }
}

现在,实际情况是我不能只将ISomeService的依赖项添加到我的控制器中并完成它。我需要根据用户告诉我的内容选择IService的实现,我可能需要创建他们选择的服务的多个副本。

也许我有一个允许我按类型解析我需要的ISomeService实例的类:

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
    }

}

所以我可以

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();
     }

}

似乎Autofac的委托工厂在这里不合适,我不知道该怎么做(除了使用服务定位器)。有什么建议吗?

1 个答案:

答案 0 :(得分:2)

这是你需要的吗? Service types, names and keys

  

可以使用服务名称进一步识别服务。使用这种技术,Named()注册方法取代了As()。

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

要检索命名服务,请执行   使用ResolveNamed()方法:

var r = container.ResolveNamed<IDeviceState>("online");