Настройка профилей с помощью StructureMap - PullRequest
7 голосов
/ 19 февраля 2009

важно ; Я действительно ищу StructureMap ответа здесь. Пожалуйста, не говорите, как это сделать с Windsor, Spring, Unity или любым из остальных .

Я играю с StructureMap для IoC - и в основном моя цель состоит в том, чтобы иметь профиль по умолчанию, который определяет основные типы, и ряд именованных профилей, которые переопределяют / расширяют это. Я думаю , что профили могут это делать, но я просто не могу заставить его работать ни через xml, ни через API кода. В частности, если я пытаюсь загрузить контейнер для профиля:

container = new Container();
container.SetDefaultsToProfile(profile);

Затем я получаю «Запрошенный профиль {имя} не может быть найден», несмотря на то, что я четко назвал CreateProfile при инициализации (с таким именем).

Я лаю не на том дереве?

(также опубликовано для группы пользователей )


В идеале я хочу определить стандарт (/ default) типы, а затем для ряда различных именованных конфигураций, переопределить некоторые настройки - т. е. если бы у меня было

  • global: IFoo => Foo, IBar => Bar
  • configA: (без изменений)
  • configB: IFoo => SpecialFoo

Я считаю, что это может отображаться в 2 контейнерах, загруженных с использованием именованных профилей. Цель состоит в том, что если я попрошу любой контейнер для IBar, я получу Bar - но configA возвращает Foo (для IFoo), где configB возвращает SpecialFoo.

Может кто-нибудь подсказать, как я могу это настроить? Либо XML, либо Код в порядке ... Я просто хочу, чтобы он работал. Все, что мне нужно, это интерфейс сопоставления бетонного типа (без специальных настроек config / property).

Ответы [ 2 ]

9 голосов
/ 25 февраля 2009

Хитрость заключается в том, чтобы убедиться, что каждый профиль соответствует как минимум правилу, определенному в нем. Если вы не укажете правило (configA), оно не создаст / не увидит профиль.

Учитывая эти классы:

public interface IFoo { string SayHello(); }
public class Foo : IFoo { public string SayHello() { return "Hello"; } }
public class SpecialFoo : IFoo { public string SayHello() { return "Hello Special"; } }

public interface IBar { }
public class Bar : IBar { }

public interface IDummy { }
public class Dummy : IDummy{ }

Вы можете определить этот реестр:

public class MyRegistry : Registry
{
    protected override void configure()
    {
        ForRequestedType<IBar>().TheDefault.Is.OfConcreteType<Bar>();
        ForRequestedType<IFoo>().TheDefault.Is.OfConcreteType<Foo>();
        CreateProfileNotEmpty("configA");
        CreateProfileNotEmpty("configB")
            .For<IFoo>().UseConcreteType<SpecialFoo>();
    }
    StructureMap.Configuration.DSL.Expressions.ProfileExpression CreateProfileNotEmpty(string profile)
    {
        return CreateProfile(profile)
            .For<IDummy>().UseConcreteType<Dummy>();
    }
}

И он будет работать с этими тестами:

[TestMethod]
public void TestMethod1()
{
    var container = new Container(new MyRegistry());
    Assert.IsNotNull(container.GetInstance<IBar>());
    Assert.AreEqual("Hello", container.GetInstance<IFoo>().SayHello());

    container.SetDefaultsToProfile("configB");
    Assert.IsNotNull(container.GetInstance<IBar>());
    Assert.AreEqual("Hello Special", container.GetInstance<IFoo>().SayHello());

    container.SetDefaultsToProfile("configA");
    Assert.IsNotNull(container.GetInstance<IBar>());
    Assert.AreEqual("Hello", container.GetInstance<IFoo>().SayHello());
}

если вы замените CreateProfileNotEmpty на простой CreateProfile, произойдет сбой в строке, в которой по умолчанию задано значение configA.

1 голос
/ 30 сентября 2009

Посмотрите это видео, он показывает другой способ создания профиля по умолчанию и использование других именованных профилей, которые будут действовать как варианты.

http://www.dimecasts.net/Casts/CastDetails/135

...