如何在structuremap中进行装饰?

时间:2015-07-30 08:09:50

标签: c# dependency-injection structuremap

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

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.ProjectServiceLogDecorator   3.)Project.Services.Projects.ProjectServiceLogDecorator的实例   4.)Project.Services.Projects.IProjectService的FuncInterceptor:IContext.GetInstance()   5.)Project.Services.Projects.ProjectService   6.)Project.Services.Projects.IProjectService(Project.Services.Projects.ProjectService)的实例   7.)新的UsersController( IUserService的默认值 IService的默认值 IUserNotificationService的默认值,    IService的默认值 IProjectService的默认值 ILicenseGroupService的默认值)   8.)Project.Web.Api.Controllers.UsersController   9.)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>()
    )
);

1 个答案:

答案 0 :(得分:6)

虽然有no documentation yet,但有一整套unit tests显示了配置装饰器模式的所有不同方法。我相信你想要的是:

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