Решить все не работает

У меня есть код, который выглядит примерно так. При попытке сделать ResolveAll я ожидал, что каждый тип, зарегистрированный с помощью IParserType, будет получен из экземпляра контейнера. Но я не получил ни одного экземпляра от Unity. Я предполагаю или делаю что-то неправильно здесь.

public class ResolveAllDemo
{
    public ResolveAllDemo()
    {
        var container = new UnityContainer();

        container.RegisterInstance<IUnityContainer>(container);
        container.RegisterType<IParser, SuperParser>();
        container.RegisterType<IParser, DefaultParser>();
        container.RegisterType<IParser, BasicParser>();
        //   container.RegisterType<Crawler>();
        container.RegisterType<IParserFactory, UnityParserFactory>();

        foreach (var registeredMember in container.ResolveAll<IParser>())
        {
            LoggingUtility.LogerInstance.Logger.Write(registeredMember);
        }
    }

    #region Resolve Demo

    public interface IParserFactory
    {
        IEnumerable<IParser> BuildParsers();
    }

    public class UnityParserFactory : IParserFactory
    {
        private IUnityContainer _container;

        public UnityParserFactory(IUnityContainer container)
        {
            _container = container;
        }

        public IEnumerable<IParser> BuildParsers()
        {
            return _container.ResolveAll<IParser>();
        }
    }

    public class DefaultParser : IParser
    {
        public override string ToString()
        {
            return "DefaultParser";
        }
    }

    public class BasicParser : IParser
    {
        public override string ToString()
        {
            return "BasicParser";
        }
    }

    public class SuperParser : IParser
    {
        public override string ToString()
        {
            return "SuperParser";
        }
    }

    public interface IParser
    {
    }

    #endregion Resolve Demo
}

person Arshad Badar Khan    schedule 03.02.2012    source источник


Ответы (2)


Вы не регистрируете 3 разные реализации IParser. Вы создаете одно сопоставление по умолчанию IParser -> SuperParser, затем перезаписываете его IParser -> DefaultParser, а затем снова перезаписываете его IParser -> BasicParser.

Если вы хотите зарегистрировать все три из них, вы должны предоставить именованные регистрации, например

container.RegisterType<IParser, SuperParser>("Super");
container.RegisterType<IParser, DefaultParser>("Default");
container.RegisterType<IParser, BasicParser>("Basic");

Кроме того, ResolveAll не включает сопоставление по умолчанию (без имени). Он разрешает только те сопоставления IParser, которые были зарегистрированы как именованные сопоставления.

person Sebastian Weber    schedule 03.02.2012
comment
Знаете ли вы, является ли тот факт, что значение по умолчанию не возвращается, преднамеренным или это ошибка? - person Nicolas Irisarri; 12.03.2015
comment
@NicolasIrisarri Помимо того факта, что он находится в кодовой базе, по крайней мере, с версии 1.2, я считаю, что это задумано. Вы можете легко обойти это, если снова зарегистрируете сопоставление по умолчанию с именем (например, по умолчанию). - person Sebastian Weber; 12.03.2015
comment
это действительно ценная информация. единство ведет себя таким образом не имеет никакого смысла - person vip32; 13.12.2016
comment
Я думаю, что Unity действительно должна генерировать исключение, а не просто перезаписывать или, что еще лучше, делать поведение по умолчанию, когда Unity регистрирует зарегистрированный тип как имя. - person Jonas Stensved; 10.03.2017
comment
@JonasStensved Другие контейнеры запоминают несколько регистраций по умолчанию и используют их для создания цепочек объектов во время разрешения. Unity перезаписывает эту регистрацию. Разные контейнеры, разное поведение. Но вы всегда можете расширить Unity в соответствии со своими предпочтениями. - person Sebastian Weber; 13.03.2017
comment
Unity действительно ужасный POS - person ; 24.05.2018

Вам нужно зарегистрировать свои парсеры с именем, если вы хотите разрешить все парсеры из контейнера.

Вот код обновления из вашего конструктора:

public ResolveAllDemo() 
{

  var container = new UnityContainer();

  container.RegisterType<IParser, SuperParser>("SuperParser");
  container.RegisterType<IParser, DefaultParser>("DefaultParser");
  container.RegisterType<IParser, BasicParser>("BasicParser");

  container.RegisterType<IParserFactory, UnityParserFactory>();

  foreach (var registeredMember in container.ResolveAll<IParser>())
  {
     LoggingUtility.LogerInstance.Logger.Write(registeredMember);
  }
}

Примечание.

В следующем коде нет необходимости, потому что контейнер регистрируется во время создания контейнера.

container.RegisterInstance<IUnityContainer>(container);
// not needed cause UnityContainer registers itself on construction
person Jehof    schedule 03.02.2012
comment
Спасибо, ваш ответ действительно избавил меня от многих ошибок сегодня! - person Petko Petkov; 27.09.2012