tags:

views:

175

answers:

1

I'm using StructureMap, v. 2.5.3 and am having trouble with chaining together implementations on an interface to implement the Decorator pattern.

I'm used to Windsor, where it is possible to name variations on interface implementations and send the named impl. into another (default) impl.

This is the default, non decorated version, which works fine:

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

This is the ctor on the decorator, that I want to call:

public CommentAuditService( ICommentService commentService, 
                            IAuditService auditService )

This works, but does not give me access to the decorated object:

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

This takes me int an inf. loop:

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

So far this is what seems to me should work:

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

However it send it into an endless loop of creating new instances of CommentAuditService

Does anyone have an quick answer? (other than switching to Castle.Windsor, which I'm very close to at the moment)

+6  A: 

You were very close. Try:

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

If AuditService might itself have dependencies, you would do:

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

Or, if you change the last part to:

ioc.GetInstance<IAuditService>()

you can register the concrete type of your audit service separately.

Joshua Flanagan
Thats the ticket! Thanks Joshua
iammaz