2009-08-17 2 views
2

Я сделал довольно много поискового запроса и искал здесь на SO, но не мог найти аналогичный вопрос или ответ.Как настроить именованные экземпляры с использованием профилей StructureMap?

В типичной конфигурации SM можно добавить несколько именованных экземпляров для одного PluginType:

ForRequestedType<IFoo>() 
    .AddInstances(x => { 
     x.OfConcreteType<FooA>().WithName("FooA"); 
     x.OfConcreteType<FooB>().WithName("FooB"); 
    }); 

Нет проблем нет. Проблема в том, что я не могу сделать то же самое при создании профиля. Большинство примеров, объясняющие, как использовать профили использовать For<>() метод пройденных ProfileExpression:

CreateProfile("Default", p => { 
    p.For<IFoo>().UseConcreteType<FooC>(); 
    }); 

Я не могу показаться, чтобы найти способ, чтобы добавить несколько именованных экземпляры для того же PluginType, как вы можете сделать выше штатной конфигурацию. Единственный другой метод, доступный через ProfileExpression, - Type<>(), но я не уверен, что его можно использовать для этой цели.

Edit: Я пытался использовать Type<>() вместо For<>() и это, кажется, принимая меня в правильном направлении, но я столкнулся с другой проблемой. Чтобы лучше объяснить, что здесь лучший пример того, что я пытаюсь сделать (это то, что я отправил в группу StructureMap-пользователей, нет ответа еще нет):

ObjectFactory.Initialize(x => { 
    x.CreateProfile("Nissan", p => 
    { 
     p.Type<ICar>().Is.OfConcreteType<NewNissanCar>().WithName("New"); 
      p.Type<ICar>().Is.OfConcreteType<OldNissanCar>().WithName("Old"); 
    }); 

    x.CreateProfile("Honda", p => 
    { 
     p.Type<ICar>().Is.OfConcreteType<NewHondaCar>().WithName("New"); 
     p.Type<ICar>().Is.OfConcreteType<OldHondaCar>().WithName("Old"); 
    }); 

}); 

ObjectFactory.Profile = "Nissan"; 

ICar newCar = ObjectFactory.GetNamedInstance<ICar>("New"); // -> returns NewHondaCar 
ICar car = ObjectFactory.GetInstance<ICar>(); // -> returns OldNissanCar 

Так что даже если я установить профиль на " Nissan ", GetNamedInstance<>("New") возвратил экземпляр из неправильного профиля - он должен был вернуть NewNissanCar вместо NewHondaCar.

Интересно, что GetInstance<>() использует правильный профиль, а потому, что я не могу передать имя экземпляра, он возвращает произвольный конкретный тип из этого профиля, который реализует ICar (я предполагаю, что это просто возвращает последний конкретный тип добавляемый для этого интерфейса) ,

ответ

0

Я не 100% уверен в синтаксисе, но я считаю, что это правильно:

container = new Container(x => { 

    x.ForRequestedType<IFoo>() 
     .AddInstances(y => 
     { 
      y.OfConcreteType<FooA>().WithName("FooA"); 
      y.OfConcreteType<FooB>().WithName("FooB"); 
     }); 

    x.CreateProfile("Default") 
     .For<IFoo>().UseNamedInstance("FooA"); 

}); 
+0

Это будет работать, если я захочу повторно использовать существующий именованный экземпляр. К сожалению, я бы хотел зарегистрировать новый конкретный тип и дать ему имя. Посмотрев на пример, который я дал в вопросе, я думаю, что я не должен был снова использовать FooA в профиле. Я попытаюсь исправить это, чтобы уточнить мои намерения. – khaledh

0

Это не выглядит как StructureMap отношениях именованных экземпляров на профильном уровне. Я просто попробовал пример автомобиля с SM 2.6.3 и получил те же результаты. Вы также можете увидеть его на выходе ObjectFactory.WhatDoIHave():

ICar (ConsoleApplication1.ICar)      
Scoped as: Transient 
     "New" Configured Instance of ConsoleApplication1.NewHondaCar, ConsoleApplication1 
     "Old" Configured Instance of ConsoleApplication1.OldHondaCar, ConsoleApplication1 

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

ICar (ConsoleApplication1.ICar)      
Scoped as: Transient 
     "Default Instance for Profile Nissan" Configured Instance of ConsoleApplication1.NewNissanCar, ConsoleApplication1 
     "Default Instance for Profile Honda" Configured Instance of ConsoleApplication1.NewHondaCar, ConsoleApplication1 

Обратите внимание, как имя профиля на самом деле часть имени ключа экземпляра. Я не прошел код, но это то, что, похоже, происходит.