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>()
)
);
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With