C# StructureMap 4构造函数与命名实例的依赖关系
我想使用StructureMap 4实现这个功能。 我创建了一个接口IDEDeveloper和两个实现 CSharpDeveloper(装饰类型)和developerCorator 哪个是装饰师。 decorator类型依赖于idedeveloper,类本身实现了IDevloper,这意味着其中一个类型应该是命名实例。 命名实例是CSharpDeveloper 我想将developerCorator注册为一个idedeveloper,我可以使用未命名的GetInstance重载函数解析该类型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
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();
}