C# StructureMap 4构造函数与命名实例的依赖关系

C# StructureMap 4构造函数与命名实例的依赖关系,c#,ioc-container,structuremap,constructor-injection,C#,Ioc Container,Structuremap,Constructor Injection,我想使用StructureMap 4实现这个功能。 我创建了一个接口IDEDeveloper和两个实现 CSharpDeveloper(装饰类型)和developerCorator 哪个是装饰师。 decorator类型依赖于idedeveloper,类本身实现了IDevloper,这意味着其中一个类型应该是命名实例。 命名实例是CSharpDeveloper 我想将developerCorator注册为一个idedeveloper,我可以使用未命名的GetInstance重载函数解析该类型 c

我想使用StructureMap 4实现这个功能。 我创建了一个接口IDEDeveloper和两个实现 CSharpDeveloper(装饰类型)和developerCorator 哪个是装饰师。 decorator类型依赖于idedeveloper,类本身实现了IDevloper,这意味着其中一个类型应该是命名实例。 命名实例是CSharpDeveloper

我想将developerCorator注册为一个idedeveloper,我可以使用未命名的GetInstance重载函数解析该类型

container.GetInstance<IDeveloper>();
我尝试过使用依赖项,但没有任何效果

public void Register(TypeMap typeMap, ITypeMapCollection dependencies = null) {
    container.Configure(x => {
        var use = x.For(typeMap.ServiceType)
                   .Add(typeMap.ConcreteType);

        if (typeMap.Name.IsNotNullOrEmpty()) {
            use.Named(typeMap.Name);
        }

        if (dependencies.IsNotNullOrEmpty()) {
            dependencies.ForEach(dependency => {
                use.Dependencies.Add(dependency.Name, dependency.ServiceType);
            });
        }
    });
}

谢谢。

我通过为Use方法提供一个表达式树来创建实例并通过容器解析所有依赖项,从而成功地做到了这一点

public void Register(TypeMap typeMap, ITypeMapCollection dependencies = null) {
    container.Configure(x => {
        var use = x.For(typeMap.ServiceType)
                   .Use(typeMap.ConcreteType);

        if (typeMap.Name.IsNotNullOrEmpty()) {
            use.Named(typeMap.Name);
        }

        if (dependencies.IsNotNullOrEmpty()) {
            x.For(typeMap.ServiceType).Use("composite", BuildExpression(typeMap, dependencies));
        }
    });
}

private Func<IContext, object> BuildExpression(TypeMap typeMap, ITypeMapCollection dependencies) {
    var contextParameter = Expression.Parameter(typeof(IContext), "context");
    var @params = dependencies.ToArray(d => d.ServiceType);
    var ctorInfo = typeMap.ConcreteType.GetConstructor(@params);
    var genericMethodInfo = typeof(IContext).GetMethods().First(method => {
        return method.Name.Equals("GetInstance") &&
                method.IsGenericMethodDefinition &&
                method.GetParameters().Length == 1;
    });

    var getInstanceCallExpressions = dependencies.Select(dependency => {
        var nameParam = Expression.Constant(dependency.Name, typeof(string));
        var methodInfo = genericMethodInfo.MakeGenericMethod(new[] { dependency.ServiceType });

        return Expression.Call(contextParameter, methodInfo, new[] { nameParam });
    });

    var lambda = Expression.Lambda<Func<IContext, object>>(
                    Expression.New(ctorInfo, getInstanceCallExpressions),
                    contextParameter);

    return lambda.Compile();
}
public class TypeMap
{
    public string Name { get; set; }
    public Type ServiceType { get; set; }
    public Type ConcreteType { get; set; }
}
public void Register(TypeMap typeMap, ITypeMapCollection dependencies = null) {
    container.Configure(x => {
        var use = x.For(typeMap.ServiceType)
                   .Add(typeMap.ConcreteType);

        if (typeMap.Name.IsNotNullOrEmpty()) {
            use.Named(typeMap.Name);
        }

        if (dependencies.IsNotNullOrEmpty()) {
            dependencies.ForEach(dependency => {
                use.Dependencies.Add(dependency.Name, dependency.ServiceType);
            });
        }
    });
}
public void Register(TypeMap typeMap, ITypeMapCollection dependencies = null) {
    container.Configure(x => {
        var use = x.For(typeMap.ServiceType)
                   .Use(typeMap.ConcreteType);

        if (typeMap.Name.IsNotNullOrEmpty()) {
            use.Named(typeMap.Name);
        }

        if (dependencies.IsNotNullOrEmpty()) {
            x.For(typeMap.ServiceType).Use("composite", BuildExpression(typeMap, dependencies));
        }
    });
}

private Func<IContext, object> BuildExpression(TypeMap typeMap, ITypeMapCollection dependencies) {
    var contextParameter = Expression.Parameter(typeof(IContext), "context");
    var @params = dependencies.ToArray(d => d.ServiceType);
    var ctorInfo = typeMap.ConcreteType.GetConstructor(@params);
    var genericMethodInfo = typeof(IContext).GetMethods().First(method => {
        return method.Name.Equals("GetInstance") &&
                method.IsGenericMethodDefinition &&
                method.GetParameters().Length == 1;
    });

    var getInstanceCallExpressions = dependencies.Select(dependency => {
        var nameParam = Expression.Constant(dependency.Name, typeof(string));
        var methodInfo = genericMethodInfo.MakeGenericMethod(new[] { dependency.ServiceType });

        return Expression.Call(contextParameter, methodInfo, new[] { nameParam });
    });

    var lambda = Expression.Lambda<Func<IContext, object>>(
                    Expression.New(ctorInfo, getInstanceCallExpressions),
                    contextParameter);

    return lambda.Compile();
}