.net 具有structuremap 2.6的装饰器模式

.net 具有structuremap 2.6的装饰器模式,.net,inversion-of-control,structuremap,.net,Inversion Of Control,Structuremap,我正在使用StructureMap 2.6并尝试使用装饰器模式: For<IBusRefTranslator>().Use<BusRefTranslator>() .EnrichWith((x) => new LoggingBusRefTranslator(x)) .Ctor<string>("connectionString").Is(connectionString); For()。使

我正在使用StructureMap 2.6并尝试使用装饰器模式:

        For<IBusRefTranslator>().Use<BusRefTranslator>()
            .EnrichWith((x) => new LoggingBusRefTranslator(x))
            .Ctor<string>("connectionString").Is(connectionString);
For()。使用()
.EnrichWith((x)=>新的LoggingBusRefTranslator(x))
.Ctor(“连接字符串”).Is(连接字符串);

这工作得很好,但是我的LoggingBusRefTranslator有一个需要解决的依赖项,所以我希望StructureMap来构建它。我就是想不出正确的路线,我能找到的大多数充实示例都使用旧语法。

我已经设法解决了这个问题,将我的装饰器的所有依赖项移到构造函数依赖项,并使用EnrichWith扩展的另一种形式:

        For<IBusRefTranslator>().Use<BusRefTranslator>()
            .EnrichWith<IBusRefTranslator>((c, x) => new LoggingBusRefTranslatorDecorator(x, c.GetInstance<IFusionLogService>()))
            .Ctor<string>("connectionString").Is(connectionString);
For()。使用()
.EnrichWith((c,x)=>新的LoggingBusRefTranslatorDecorator(x,c.GetInstance())
.Ctor(“连接字符串”).Is(连接字符串);

我自己通过编写以下扩展方法解决了这个问题。优点是配置的语法更简单,装饰器的依赖项会自动注入,而不必自己在
新的
语句中处理它们。装饰对象的语法如下所示:

For<IBusRefTranslator>().Use<BusRefTranslator>()
    .Decorate().With<LoggingBusRefTranslatorDecorator>(); // dependencies and decoratee automatically injected
For()。使用()
.用()装饰();//自动注入依赖项和装饰对象
扩展类:

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;
        }
    }
公共静态类StructureMappExtensions
{
/// 
///将定义的实例配置为由另一个装饰器类型的实例包装
/// 
公共静态装饰图装饰(此SmartInstance实例)
{
返回新的decoreconfig(实例);
}
公共类装饰图
{
私有只读SmartInstance\u实例;
内部装饰图(SmartInstance实例)
{
_实例=实例;
}
私有静态IEnumerable GetTypeAndAllBaseTypes(类型t)
{
if(t==typeof(object))
屈服断裂;
收益率t;
foreach(t.GetInterfaces().Union(GetTypeAndAllBaseTypes(t.BaseType))中的var@base)
基准收益率;
}
私有静态字符串findargumentnameforwrappedennine(类型decoratorType)
{
foreach(GetTypeAndAllBaseTypes中的var t(typeof(t)))
{
var argumentName=新插件(decoratorType).FindArgumentNameForType(t,CannotFindProperty.Ignore);
if(argumentName!=null)
返回参数名;
}
抛出新的ConfigurationErrorsException(“Type”+decoratorType+”没有类型为“+typeof(T)”的构造函数参数);
}
带有()的公共SmartInstance
{
var decoratorInstance=new SmartInstance();
_EnrichWith((上下文,内部)=>decoratorInstance
.WithTorArg(用于包装的FindArgumentName(类型为(TDecorator))).EqualTo(内部)
.Build(typeof(TDecorator),(BuildSession)上下文);
返回装饰状态;
}
}