2012-08-13 73 views
1

Autofac是否支持通过名称解析服务?或者我必须总是指定一种服务类型?Autofac仅按名称解析?

我想做的事:

container.ResolveNamed("Plugin"); // or container.TryResolvedNamed("Plugin", out instance); 

container.ResolvedNamed<ISomeInterface>("Plugin"); // etc 

其中 “插件” 是注册名称/键,不是一个类型。

谢谢!

+0

这没有意义,除非你想让它返回'object'。 – SLaks 2012-08-13 22:03:05

+0

其实,这很好,因为我在Xaml绑定环境中。实际上,它是与Caliburn相关的一个小集成部分,如果这有助于提供更大的上下文。 Caliburn的Bind类有一个方法,试图通过名称来解析所选的IoC容器,而不是类型。 – robcecil 2012-08-13 22:09:29

+0

具体而言:Bind.ModelChanged(...)是有问题的方法。它尝试通过使用以下行的IoC容器进行检索: target = IoC.GetInstance(null,containerKey); 因此,Caliburn假设提供的IoC风格将支持以这种方式进行检索。不确定Autofac是否能够以这种方式工作。 (IoC只是Caliburn源代码中的一个门面类,它抽象出任何容器的细节......) – robcecil 2012-08-13 22:14:22

回答

0

这是我如何解决了这个问题:

private Type GetTypeForName(string key) 
    { 
     return (
      from reg in Container.ComponentRegistry.Registrations 
      from service in reg.Target.Services.OfType<KeyedService>() 
      .Where(service => service.ServiceKey.ToString() == key) 
      select service.ServiceType).FirstOrDefault(); 
    } 

显然,不是一个完美的解决方案,因为它是可以想象可能有多个注册使用相同的密钥。

1

您必须指定一个Type在Autofac解析服务,或者通过泛型参数或Type参数。两种选择:

  1. 注册所有相关服务和附加.Named<object>("service name")
  2. 维护您自己的Dictionary<string, Type>,以便在通过Autofac解析之前自己查看类型。

我可能会去选择1,假设你已经控制了所有的注册码。

0

如果您维护服务之间的密钥的唯一性,这个扩展方法将帮助:

private static object ResolveSingleOrDefaultByName(this IComponentContext cc, string name) 
    { 
     var reg = cc.ComponentRegistry.Registrations.SingleOrDefault(r => 
      r.Services.OfType<KeyedService>().Any(s => name.Equals(s.ServiceKey))); 
     return reg == null ? null : cc.ResolveComponent(reg, Enumerable.Empty<Parameter>()); 
    } 

它会返回null,如果没有找到关键。