2012-03-05 79 views
3

我使用StructureMap 2.6,并试图使用Decorator模式Decorator模式:与structuremap 2.6

 For<IBusRefTranslator>().Use<BusRefTranslator>() 
      .EnrichWith((x) => new LoggingBusRefTranslator(x)) 
      .Ctor<string>("connectionString").Is(connectionString); 

这完美的作品,但我LoggingBusRefTranslator有需要解决的依赖关系,所以我想StructureMap建立它。我无法弄清楚正确的路线和丰富的大多数例子,我可以使用旧的语法。

回答

2

我已经设法通过移动我的所有依赖我的装饰来构造依赖和使用EnrichWith延伸的另一种形式来解决这个问题:

 For<IBusRefTranslator>().Use<BusRefTranslator>() 
      .EnrichWith<IBusRefTranslator>((c, x) => new LoggingBusRefTranslatorDecorator(x, c.GetInstance<IFusionLogService>())) 
      .Ctor<string>("connectionString").Is(connectionString); 
3

我已经写了下面的扩展方法解决了这个自己。优点是配置的语法更简单,并且装饰器的依赖关系自动注入,而不必在new语句中自己处理它们。用于装饰的对象是作为语法如下:

For<IBusRefTranslator>().Use<BusRefTranslator>() 
    .Decorate().With<LoggingBusRefTranslatorDecorator>(); // dependencies and decoratee automatically injected 

扩展类:

public static class StructureMapExtensions 
{ 
    /// <summary> 
    /// Configures the defined instance to be wrapped by an instance of another decorator type 
    /// </summary> 
    public static DecorateConfig<T> Decorate<T>(this SmartInstance<T> instance) 
    { 
     return new DecorateConfig<T>(instance); 
    } 

    public class DecorateConfig<T> 
    { 
     private readonly SmartInstance<T> _instance; 
     internal DecorateConfig(SmartInstance<T> instance) 
     { 
      _instance = instance; 
     } 

     private static IEnumerable<Type> GetTypeAndAllBaseTypes(Type t) 
     { 
      if (t == typeof(object)) 
       yield break; 

      yield return t; 

      foreach (var @base in t.GetInterfaces().Union(GetTypeAndAllBaseTypes(t.BaseType))) 
       yield return @base; 
     } 

     private static string FindArgumentNameForWrappedInner(Type decoratorType) 
     { 
      foreach (var t in GetTypeAndAllBaseTypes(typeof(T))) 
      { 
       var argumentName = new Plugin(decoratorType).FindArgumentNameForType(t, CannotFindProperty.Ignore); 
       if (argumentName != null) 
        return argumentName; 
      } 

      throw new ConfigurationErrorsException("Type " + decoratorType + " has no constructor arguments of type " + typeof(T)); 
     } 

     public SmartInstance<TDecorator> With<TDecorator>() 
     { 
      var decoratorInstance = new SmartInstance<TDecorator>(); 
      _instance.EnrichWith((context, inner) => decoratorInstance 
       .WithCtorArg(FindArgumentNameForWrappedInner(typeof(TDecorator))).EqualTo(inner) 
       .Build(typeof (TDecorator), (BuildSession) context)); 

      return decoratorInstance; 
     } 
    }