StructureMap и шаблон декоратора - PullRequest
       15

StructureMap и шаблон декоратора

14 голосов
/ 18 сентября 2009

Я использую StructureMap, v. 2.5.3, и у меня проблемы с объединением реализаций в интерфейсе для реализации шаблона Decorator.

Я привык к Виндзору, где можно назвать варианты реализации интерфейса и отправить именованный импл. в другой (по умолчанию) импл.

Это стандартная версия без оформления, которая отлично работает:

ObjectFactory.Initialize(registry =>
{
  registry.ForRequestedType<ICommentService()
    .TheDefault.Is.OfConcreteType<CommentService>();
... }

Это ctor на декораторе, который я хочу назвать:

public CommentAuditService( ICommentService commentService, 
                            IAuditService auditService )

Это работает, но не дает мне доступа к украшенному предмету:

registry.ForRequestedType<ICommentService>()
  .TheDefault.Is.OfConcreteType<CommentService>()
  .EnrichWith(x => new CommentAuditService());

Это займет у меня инф. цикл:

registry.ForRequestedType<ICommentService>()
  .TheDefault.Is.OfConcreteType<CommentService>()
  .EnrichWith(x => new CommentAuditService( new CommentService(), 
                                            new AuditService()));

Пока это то, что мне кажется должно работать:

registry.ForRequestedType<ICommentService.()
  .TheDefault.Is.OfConcreteType<CommentAuditService>()
  .WithCtorArg("commentService")
  .EqualTo(new CommentService());

Однако он отправляет его в бесконечный цикл создания новых экземпляров CommentAuditService

У кого-нибудь есть быстрый ответ? (кроме переключения на Castle.Windsor, с которым я сейчас очень близок)

1 Ответ

21 голосов
/ 18 сентября 2009

Вы были очень близки. Попробуйте:

registry.ForRequestedType<ICommentService>()
    .TheDefaultIsConcreteType<CommentService>()
    .EnrichWith(original => new CommentAuditService(original, 
                                         new AuditService()));

Если AuditService сам может иметь зависимости, вы должны сделать:

registry.ForRequestedType<ICommentService>()
    .TheDefaultIsConcreteType<CommentService>()
    .EnrichWith((ioc, original) => new CommentAuditService(original, 
                                   ioc.GetInstance<AuditService>()));

Или, если вы измените последнюю часть на:

ioc.GetInstance<IAuditService>()

вы можете отдельно зарегистрировать конкретный вид вашей аудиторской службы.

...