StructureMap и узор декоратора

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

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

Это стандартная, не украшенная версия, которая отлично работает:

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());

Это заставляет меня int inf. loop:

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

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

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>()

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