5
// Enrich with is enriching more than i want
 
public intefrace ICommand {
   void Execute();
}

// classes

public class A : ICommand {}
public class B : ICommand {}
public class MultiCommand : ICommand {
  public MultiCommand(ICommand[] commands) {}
}

// -- decorators
public DecoratorOne : ICommand {
  public DecoratorOne(Icommand toDecorate) {}
}

public DecoratorTwo : ICommand {
  public DecoratorOne(Icommand toDecorate) {}
}



// what i tried

 ForREquesedType<ICommand>()
    .TheDefaultIsConcreteType<A>
    .EnrichWith(x => new DecoratorOne(x)
    .EnrichWith(y => new DecoratorTwo(y)
    .CacheBy(InstanceScope.Singleton);

 InstanceOf<ICommand>()
    .TheDefault.Is.OfConcreteType<B>
    .EnrichWith(x => new DecoratorOne(x)
    .WithName("secondCommand")

            ForRequestedType<MultiCommand>()
                .TheDefault.Is.OfConcreteType<MultiCommand>()
                .TheArrayOf<ICommand>()
                .Contains(y =>
                              {
                                  y.TheDefault();
                                  y.TheInstanceNamed("secondCommand")
                              })
                .WithName("multi");

**

/// 我想做的事

**

我想要的是 A 是默认值。因此,任何需要 ICommand 实例的地方都会得到 A。MultiCommand 将同时具有 A 和 B,并将在循环中执行它们。

**

// 我遇到的问题

**

B好像装修了几次。当我打电话时ObjectFactory.GetNamedInsance<ICommand>("secondCommand"),我得到了一些新的**new DecoratorOne(new DecorateOne(B)).** 我假设它正在被装饰,因为我对默认值的定义是 A。我怎样才能避免这种情况?

这也是将数组注入多命令的正确方法吗?

再次感谢,我是结构图的新手,因此将不胜感激。

更新

我最终做的是创建一个 TypeInterceptor 的子类,它适当地修饰了类型。这对我来说感觉不对,但它比在我的代码中使用“新”要好。所以代码变成了

        RegisterInterceptor(new CommandDecoratorInterceptor());

        // this is the default that everyone hooks into
        ForRequestedType<ICOmmand>()
            .TheDefaultIsConcreteType<A>()
            .CacheBy(StructureMap.Attributes.InstanceScope.Singleton);

        InstanceOf<ICommand>()
            .Is.OfConcreteType<B>()
            .WithName("secondCommand");


        ForRequestedType<MultiCommand>()
            .TheDefault.Is.OfConcreteType<MultiCommand>()
            .TheArrayOf<ICommand>()
            .Contains(y =>
                          {
                              y.TheDefault();
                              y.TheInstanceNamed("secondCommand");
                          });

然后新的类型拦截器像以前一样装饰类。这允许 MultiMonitor 避免被装饰(丰富)。

任何有关改进这一点的建议将不胜感激;)

4

1 回答 1

4

在丰富之前不要使用 TheDefaultIsConcreteType。这就像在 ForRequestedType() 之后立即执行此操作一样,这表示您要丰富所有 ICommand。请改用 TheDefault.Is.OfConcreteType。

也不要加倍丰富,替换实例时它不会很好地链接。以下应该适用于您的方案:

    ForRequestedType<ICommand>()
        .CacheBy(StructureMap.Attributes.InstanceScope.Singleton)
        .TheDefault.Is.OfConcreteType<A>()
        .EnrichWith(x => new DecoratorTwo(new DecoratorOne(x)));
    InstanceOf<ICommand>().Is
        .OfConcreteType<B>()
        .EnrichWith(x => new DecoratorOne(x))
        .WithName("second");
    InstanceOf<ICommand>().Is
        .OfConcreteType<MultiCommand>()
        .TheArrayOf<ICommand>().Contains(y =>
        {
            y.TheDefault();
            y.TheInstanceNamed("second");
        })
        .WithName("multi");
于 2009-03-26T22:23:31.447 回答