如何在结构图中装饰

本文关键字:结构图 | 更新日期: 2023-09-27 18:05:34

我尝试装饰IProjectService,但我找不到structuremap的文档

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

我做错了什么?

exeption:

检测到双向依赖关系!检查StructureMap堆栈跟踪如下:1.)新建ProjectServiceLogDecorator(IRepository的默认,IUnitOfWork默认,IProjectService默认,IPrincipal默认,AuditEventLogger默认)2)。Project.Services.Projects.ProjectServiceLogDecorator3)。Project.Services.Projects.ProjectServiceLogDecorator的实例4.) Project.Services.Projects.IProjectService的FuncInterceptor: IContext.GetInstance()5)。Project.Services.Projects.ProjectService6)。Project.Services.Projects.IProjectService实例(Project.Services.Projects.ProjectService)7.) new UsersController(IUserService默认值,IService默认值,IUserNotificationService默认值, IService IProjectService ILicenseGroupService)的默认值8)。Project.Web.Api.Controllers.UsersController9)。Project.Web.Api.Controllers.UsersController的实例10)。Container.GetInstance (Project.Web.Api.Controllers.UsersController)

我找到了解决方案,但它是令人作呕的:

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

如何在结构图中装饰

虽然还没有文档,但是有一组完整的单元测试,展示了配置装饰器模式的所有不同方式。我相信你想要的是:

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

您可以简单地通过以下操作添加额外的装饰器。但是,请注意,最外层的装饰器是最后指定的.DecorateAllWith,因此首先指定最内层的类可能更直观。

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

结果是:

SomeOtherDecorator
    ProjectServiceLogDecorator
        ProjectService

如果你需要更多的控制,你总是可以使用智能实例来显式地将构造函数参数应用于装饰器(而不需要显式地提供所有参数)。

var projectService = For<IProjectService>().Use<ProjectService>();
For<IProjectService>().Use<ProjectServiceLogDecorator>()
    .Ctor<IProjectService>().Is(projectService);