LightCore ServiceLocator с многократной регистрацией по одному контракту - PullRequest
1 голос
/ 26 марта 2012

Мы пытаемся интегрировать LightCore как сервисный локатор по умолчанию в нашу Metadata- / ORM-Framework.Поэтому нам нравятся некоторые Регистрации по умолчанию изнутри Framework, которые пользователь-Framework (= Разработчик приложений) может каким-то образом «отменить» своими собственными реализациями (если ему вообще нравится это делать).Как это сделать с контейнерами LightCore IoC или другими контейнерами IoC?

Что мы пытались:

var builder = new ContainerBuilder();
builder.Register<Foo>().ControlledBy<SingletonLifecycle>();
builder.Register<Foo, Foo2>().ControlledBy<SingletonLifecycle>();

var container = builder.Build();

var foo = container.Resolve<Foo>();

Мы зарегистрировали два класса в качестве контракта для Foo.С помощью приведенного выше кода мы всегда получаем первое (экземпляры Foo).Так что здесь не обойтись.Кстати: нам нравится получать экземпляр Foo2.

Мы изменили его с использования конкретных классов на интерфейсы:

var builder = new ContainerBuilder();
builder.Register<IFoo, Foo>().ControlledBy<SingletonLifecycle>();
builder.Register<IFoo, Foo2>().ControlledBy<SingletonLifecycle>();

var container = builder.Build();

var foo = container.Resolve<IFoo>();

С этим на месте мы получаем исключение разрешения в Resolve <>() сказать, что регистрация не может быть найдена.Если мы удалим второе выражение «Register ()», оно будет работать так, как мы получаем экземпляр Foo.

Мы не уверены, что пропустили некоторые общие понятия.Это работает с другими IoC так же?Каков рекомендуемый способ отмены / отмены регистрации?

Любая помощь по этой теме будет полезна - не только для LightCore.

Обновление: Я настроилнекоторые тесты для вышеуказанного сценария с использованием контейнера IoC SimpleInjector.С этим контейнером нужно указать AllowOverridingRegistration = true в конструкторе, и он будет работать как положено.Таким образом, похоже, что LightCore просто не поддерживает этот вариант использования правильно, но другие делают.

Обновление: Мы получили быстрый ответ от создателя LightCore о том, что LigtCore не поддерживает переопределение регистрациисовсем.Так что, похоже, нет никакого способа справиться с переопределением регистрации этих сценариев с помощью LightCore, поэтому мы переключились с LightCore на SimpleInjector.

Следующая конфигурация SimpleInjector соответствует нашим четырем текущим требованиям:

  // Register concrete class for FooFoo
  container.RegisterSingle<FooFoo>();

  // Register concrete classes for Foo - Final registration should return FooFoo, not Foo
  container.RegisterSingle<Foo>();
  container.RegisterSingle<Foo, FooFoo>();

  // Register interfaces for IFoo - Final registration should return FooFoo, not Foo
  container.RegisterSingle<IFoo, Foo>();
  container.RegisterSingle<IFoo, FooFoo>();

  // Register list of Plugs
  container.RegisterAll(new IPlug[] { new PlugA(), new PlugB() });

Cheers, Marc

1 Ответ

1 голос
/ 27 марта 2012

AFAIK все большие DI-фреймворки (Autofac, Unity, Castle Windsor, StructureMap, Ninject) имеют функции для переопределения регистрации.Большинство из них позволяют это сделать, выполнив несколько регистраций для одного и того же типа сервиса, и они выбирают одну из регистраций в качестве стандартной.Однако какой экземпляр они выбирают, зависит от структуры.В то время как некоторые платформы выбирают первую из нескольких регистраций, другие выбирают последнюю регистрацию.Знание того, как выборочная среда делает это, важно, так как это определяет, следует ли вам регистрировать «переопределяющий» экземпляр до или после всех других.

Поскольку все эти платформы имеют различное разрешение перегрузки, я решилпусть по умолчанию простой инжектор не имеет переопределенного поведения (хотя это настраивается, как вы уже заметили).Это облегчает переход на другую платформу, которая была одной из целей разработки Simple Injector.Однако разрешение переопределения регистраций по умолчанию также может стать источником ошибок конфигурации, которые могут занимать много времени для отслеживания.Поскольку Simple Injector должен легко запускаться, имеет смысл запретить переопределение (по умолчанию).

В случае Simple Injector, когда включен AllowOverridingRegistration, новая регистрация действительно заменяет более раннюю регистрацию для того же типа.,Это отличается от других контейнеров, которые обычно хранят другие регистрации и позволяют разрешить все эти регистрации как одну коллекцию.С Simple Injector, коллекция вещей должна быть зарегистрирована отдельно и может быть переопределена отдельно.

Обо всех других контейнерах, кроме Simple Injector и больших, я не могу сказать много.Тем не менее, я думаю, что переопределение будет трудно сделать с большинством из них.

...