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

StructureMap配置接口名称不匹配的具体类

  •  1
  • Handcraftsman  · 技术社区  · 14 年前

    给定名称不匹配的具体类和接口

    Harvester_JohnDeere_Parsley : AbstractMachine, IParsleyHarvester
    Harvester_NewHolland_Sage : AbstractMachine, ISageHarvester
    Harvester_Kubota_Rosemary : AbstractMachine, IRosemaryHarvester
    

    其中接口有一个共同的父级

    IParsleyHarvester : ISpiceHarvester
    ISageHarvester : ISpiceHarvester
    IRosemaryHarvester : ISpiceHarvester
    

    如何配置StructureMap以便可以将I…Harvester的实例注入构造函数,例如。

    public ParsleyField(IParsleyHarvester parsleyHarvester)
    

    不必在注册表中分别配置每一对?例如

    For<ISageHarvester>().Use<Harvester_NewHolland_Sage>();
    

    我试过扫描

    Scan(x =>
    {
        x.AssemblyContainingType<Harvester_Kubota_Rosemary>();
        x.AddAllTypesOf<ISpiceHarvester>();
    

    但是I…Harvester接口没有被映射。

    谢谢!

    编辑 :

    两个答案都有效。@jeroenh的优点是可以添加保护子句来排除类(无论出于什么原因)。下面是一个基于@Mac对 this question .

    public class HarvesterConvention : StructureMap.Graph.IRegistrationConvention
    {
        public void Process(Type type, Registry registry)
        {
            // only interested in non abstract concrete types
            if (type.IsAbstract || !type.IsClass)
                return;
    
            // Get interface
            var interfaceType = type.GetInterface(
                "I" + type.Name.Split('_').Last() + "Harvester");
    
            if (interfaceType == null)
                throw new ArgumentNullException(
                    "type", 
                    type.Name+" should implement "+interfaceType);
    
            // register (can use AddType overload method to create named types
            registry.AddType(interfaceType, type);
        }
    }
    

    用法:

    Scan(x =>
    {
        x.AssemblyContainingType<Harvester_Kubota_Rosemary>();
        x.Convention<HarvesterConvention>();
        x.AddAllTypesOf<ISpiceHarvester>();
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   jeroenh    14 年前

    StructureMap不知道您的约定。您需要通过添加自定义注册约定来告诉它。实现IRegistrationConvention接口,并将约定添加到程序集扫描程序:

    Scan(x =>
      {
      x.Convention<MyConvention>();
      }
    
        2
  •  1
  •   Community Jaime Torres    7 年前

    我根据“Kirschstein”的答案改编了一个解决方案 this question .

    Scan(x =>
    {
        x.AssemblyContainingType<Harvester_Kubota_Rosemary>();
        x.AddAllTypesOf<ISpiceHarvester>()
         .NameBy(type => "I" + type.Name.Split('_').Last() + "Harvester");
    

    定义将具体类的名称转换为其接口名称以进行查找的方法。