代码之家  ›  专栏  ›  技术社区  ›  moribvndvs

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

  •  2
  • moribvndvs  · 技术社区  · 14 年前

    ISomeService . 等距服务 提供一个公共服务,但实现可能会有所不同。因此,它们将具有不同的依赖关系。

    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中,然后用它来完成。我将需要根据用户告诉我的内容来选择iSeries设备的实现,并且我可能需要为他们选择的服务创建多个副本。

    或许我会有一个类,允许我按类型解析所需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();
         }
    
    }
    

    1 回复  |  直到 14 年前
        1
  •  2
  •   Jeff Ogata    14 年前

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

    可以使用服务名称进一步标识服务。使用此技术,Named()注册方法将替换为()。

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

    要检索命名服务 使用ResolveNamed()方法:

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