How decorate in structuremap?
Asked Answered
B

1

6

I try it decorate IProjectService but I can't find documentation for struturemap

For<IProjectService>().Use<ProjectServiceLogDecorator>();
For<IProjectService>().Use<ProjectService>()
                      .DecorateWith((context, decorator) =>   
                                  context.GetInstance<ProjectServiceLogDecorator>());

What I do wrong?

exeption:

Bi-directional dependency relationship detected! Check the StructureMap stacktrace below: 1.) new ProjectServiceLogDecorator(Default of IRepository, Default of IUnitOfWork, Default of IProjectService, Default of IPrincipal, Default of AuditEventLogger) 2.) Project.Services.Projects.ProjectServiceLogDecorator 3.) Instance of Project.Services.Projects.ProjectServiceLogDecorator 4.) FuncInterceptor of Project.Services.Projects.IProjectService: IContext.GetInstance() 5.) Project.Services.Projects.ProjectService 6.) Instance of Project.Services.Projects.IProjectService (Project.Services.Projects.ProjectService) 7.) new UsersController(Default of IUserService, Default of IService, Default of IUserNotificationService, Default of IService, Default of IProjectService, Default of ILicenseGroupService) 8.) Project.Web.Api.Controllers.UsersController 9.) Instance of Project.Web.Api.Controllers.UsersController 10.) Container.GetInstance(Project.Web.Api.Controllers.UsersController)

I found solution but it is disgustingly:

For<IProjectService>().Use<ProjectService>().DecorateWith((ctx, service) => 
    new ProjectServiceLogDecorator(
        ctx.GetInstance<IRepository<Project>>(),
        ctx.GetInstance<IUnitOfWork>(),
        service,
        ctx.GetInstance<ILicenseService>(),
        ctx.GetInstance<IPrincipal>(),
        ctx.GetInstance<AuditEventLogger>()
    )
);
Bemoan answered 30/7, 2015 at 8:9 Comment(1)
I think you need DecorateAllWith. Related: #25134596Counselor
E
6

Although there is no documentation yet, there are a complete set of unit tests showing all of the different ways you can configure a decorator pattern. I believe the one you want is:

For<IProjectService>().DecorateAllWith<ProjectServiceLogDecorator>();
For<IProjectService>().Use<ProjectService>();

You can add additional decorators simply by doing the following. However, note that the outermost decorator is the last .DecorateAllWith specified, so it might be more intuitive to specify the innermost class first.

For<IProjectService>().Use<ProjectService>();
For<IProjectService>().DecorateAllWith<ProjectServiceLogDecorator>();
For<IProjectService>().DecorateAllWith<SomeOtherDecorator>();

Which results in:

SomeOtherDecorator
    ProjectServiceLogDecorator
        ProjectService

If you need more control than that, you can always use smart instances to apply the constructor parameters to the decorator explicitly (without needing to supply all parameters explicitly).

var projectService = For<IProjectService>().Use<ProjectService>();
For<IProjectService>().Use<ProjectServiceLogDecorator>()
    .Ctor<IProjectService>().Is(projectService);
Edmundedmunda answered 6/8, 2015 at 19:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.