Pergunta

Eu estou usando StructureMap, v. 2.5.3 e estou tendo problemas com encadeamento implementações juntos em uma interface para implementar o padrão Decorator.

Estou acostumado a Windsor, onde é possível nomear variações sobre implementações de interface e enviar o impl nomeado. em outro (default) impl.

Este é o padrão, versão não decorados, que funciona bem:

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

Este é o ctor sobre o decorador, que eu quero chamar:

public CommentAuditService( ICommentService commentService, 
                            IAuditService auditService )

Isso funciona, mas não me dá acesso ao objeto de decoração:

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

Isso leva-me int um inf. loop:

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

Até agora, este é o que me parece deve trabalho:

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

No entanto, enviá-lo em um loop infinito de criar novas instâncias de CommentAuditService

Alguém tem uma resposta rápida? (Excepto a mudança para Castle.Windsor, que estou muito perto no momento)

Foi útil?

Solução

Você estava muito perto. Tente:

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

Se AuditService pode-se ter dependências, você faria:

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

Ou, se você alterar a última parte a:

ioc.GetInstance<IAuditService>()

Você pode registrar o tipo concreto de seu serviço de auditoria separadamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top