Единство и зависимость от коллекции предметов - PullRequest
5 голосов
/ 22 марта 2011

В моем случае некоторый класс зависит не от одного объекта, а от его коллекции:

public class ImportController { ...
public ImportController(IEnumerable<IImportManager> managers) { ... }
}

public class ProductAImportManager : IImportManager { ... }
public class ProductBImportManager : IImportManager { ... }
public class ProductCImportManager : IImportManager { ... }

Я хочу создать экземпляр ImportController с помощью Unity, так как мне зарегистрировать зависимости?

Если я использую что-то вроде

unityContainer.RegisterType<IImportManager, ProductAImportManager>();
unityContainer.RegisterType<IImportManager, ProductBImportManager>();

, второй вызов просто переопределяет первый.

Есть ли способ попросить Unity найти все зарегистрированные типы, которые реализуют интерфейс IImportManager, создать экземпляры этих типов и передать последовательность объектов моему конструктору?

Ответы [ 2 ]

5 голосов
/ 23 марта 2011

Unity имеет несколько странные правила разрешения, когда дело доходит до нескольких регистраций.

  • Регистрации, сделанные без имени (то есть container.RegisterType<IInterface, Implementation>()), могут только быть разрешенными с помощьюcontainer.Resolve.

  • Регистрации, выполненные с именем, можно только разрешить с помощью container.ResolveAll<IInterface>().

Трюк, который я использую для зависимостив коллекции регистраций есть метод с двумя строками, который вызывает ResolveAll за кулисами:

public static class UnityExtensions {  
   public static void RegisterCollection<T>(this IUnityContainer container) where T : class {
    container.RegisterType<IEnumerable<T>>(new InjectionFactory(c=>c.ResolveAll<T>()));
  }
}

С этого момента использование просто в.

//First register individual types
unityContainer.RegisterType<IImportManager, ProductAImportManager>("productA");
unityContainer.RegisterType<IImportManager, ProductBImportManager>("productB");
//Register collection
unityContainer.RegisterCollection<IImportManager>();
//Once collection is registered, IEnumerable<IImportManager>() will be resolved as a dependency:
public class ImportController { ...
  public ImportController(IEnumerable<IImportManager> managers) { ... }
}
3 голосов
/ 23 марта 2011

Вы можете, с именованными типами и массивами:

unityContainer.RegisterType<IImportManager, ProductAImportManager>("a");
unityContainer.RegisterType<IImportManager, ProductBImportManager>("b");


public class ImportController { ...
   public ImportController(IImportManager[] managers) { ... }
}
...