【问题标题】:Decorating an interface with a decorator using structuremap 3 in an modular application在模块化应用程序中使用结构映射 3 使用装饰器装饰接口
【发布时间】:2014-09-13 05:51:30
【问题描述】:

我正在使用Structuremap 3 并在我的WinForm 项目中有3 个模块(每个模块都是一个类库项目):

核心模块包含:

  public class ICommandHandler<T>
  {
  }

[更新]

  public abstract class UnitOfWorkCommitCommandHandlerDecorator<TUnitOfWork, TCommand> :   ICommandHandler<TCommand>
    where TUnitOfWork : IUnitOfWork
  {
  }

模块 1 包含:

  public interface IModule1UOW: IUnitOfWork
  {
  }

  public class Module1UOW:IModule1UOW
  {
  }

  public class Module1UOWDecorator<TCommand> :UnitOfWorkCommitCommandHandlerDecorator<IModule1UOW,TCommand>
  {
      public Module1UOWDecorator(ICommandHandler<TCommand> decorated, IModule1UOW uow)
      {
        ...
      }
  } 

  public Command1
  {
  } 

Module2 包含:

  public interface IModule2UOW: IUnitOfWork
  {
  }

  public class Module2UOW:IModule2UOW
  {
  }

  public class Module2UOWDecorator<TCommand> :UnitOfWorkCommitCommandHandlerDecorator<IModule2UOW,TCommand>
      public Module2UOWDecorator(ICommandHandler<TCommand> decorated, IModule2UOW uow)
      {
        ...
      }
  } 

  public Command2
  {
  } 

并定义了以下类来配置每个模块的注册:

public class Module1Config
{
    public static void Config()
    {
        ObjectFactory.Configure(x =>
        {
            x.Scan(s =>
            {
                s.AssemblyContainingType(typeof(Command1));
                s.WithDefaultConventions();
                x.For(typeof(IModule1UOW))
                    .Use(typeof(Module1UOW))
                    .SetLifecycleTo((Lifecycles.Singleton));
                x.For(typeof(ICommandHandler<>))
                    .DecorateAllWith(typeof(Module1UOWDecorator<>));
            });
        });
    }
}
public class Module2Config
{
    public static void Config()
    {
        ObjectFactory.Configure(x =>
        {
            x.Scan(s =>
            {
                s.AssemblyContainingType(typeof(Command2));
                s.WithDefaultConventions();
                x.For(typeof(IModule2UOW))
                    .Use(typeof(Module2UOW))
                    .SetLifecycleTo((Lifecycles.Singleton));
                x.For(typeof(ICommandHandler<>))
                    .DecorateAllWith(typeof(Module2UOWDecorator<>));
            });
        });
    }
}

在我的应用程序的起点(我在 program.cs 中使用 WinForms)我调用Module1Confog.Config(),然后调用Module2Config.Config()

当我从ObjectFactory 得到一个ICommandHandler&lt;Command2&gt; 实例时,我期望一个用Module2UOWDecorator 装饰的ICommandHandler&lt;Command2&gt; 对象,但我得到一个用Module2UOWDecorator 装饰的ICommandHandler&lt;Command2&gt; 对象,又用Module1UOWDecorator 装饰。

换句话说,我期望:

Module2UOWDecorator[ICommandHandler&lt;Command2&gt;]

但我明白了

Module1UOWDecorator[Module2UOWDecorator[ICommandHandler&lt;Command2&gt;]]

有谁知道,我该如何解决这个问题?

【问题讨论】:

    标签: c# module decorator ioc-container structuremap


    【解决方案1】:

    容器 将处理在各个模块中定义的配置,并将它们全部合并到一个单独的工作配置中。 容器不会将不同的模块视为单独的配置。

    但是你仍然可以做你想做的事,因为DecorateAllWith 方法有一个可选的filter 参数来决定什么会被装饰,什么不会被装饰。

    根据上面的例子,你可以尝试这样的事情:

    x.For(typeof(ICommandHandler<>))
        .DecorateAllWith(
            typeof(Module2UOWDecorator<>),
            instance => instance.ReturnedType.Assembly == typeof(Class2).Assembly));
    

    【讨论】:

    • 我使用了你的代码,但这导致我的ICommandHandler 没有使用任何装饰器进行装饰。我怎样才能找到运行时的 instance 是什么?
    • 嗨@Masoud,我已经更新了代码 - 你可以再试一次吗?
    猜你喜欢
    • 1970-01-01
    • 2021-07-13
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-01
    • 2016-07-26
    相关资源
    最近更新 更多