当我解析数组时,有人可以解释为什么Component.Target.Activator.LimitType
显示Meta<Lazy<IFoo>>[]
而不是预期的Foo
?这是Autofac中的错误吗?如何获得预期的限制类型= Foo
?
这是一个使用Autofac 3.5.2和.Net 4.5的完整程序:
static class Program
{
static void Main()
{
var builder = new ContainerBuilder();
builder.RegisterModule<ALoggerModule>();
builder.RegisterType<Foo>()
.As<IFoo>();
var container = builder.Build();
Debug.WriteLine("Resolving Meta<Lazy<IFoo>>[]");
var metafoos = container.Resolve<Meta<Lazy<IFoo>>[]>();
foreach (var metalazyfoo in metafoos)
{
Debug.WriteLine("\tResult is: ".PadRight(39) + metalazyfoo.Value.Value.TheALogger.LimitType);
}
Debug.WriteLine("Resolving Meta<Lazy<IFoo>>");
var secondmetalazyfoo = container.Resolve<Meta<Lazy<IFoo>>>();
Debug.WriteLine("\tResult is: ".PadRight(39) + secondmetalazyfoo.Value.Value.TheALogger.LimitType);
Debug.WriteLine("Done");
}
public static string GetPrettyName(this Type type)
{
if (type.IsGenericType)
{
var genargNames = type.GetGenericArguments().Select(GetPrettyName);
var idx = type.Name.IndexOf('`');
var typename = (idx > 0) ? type.Name.Substring(0, idx) : type.Name;
return String.Format("{0}<{1}>", typename, String.Join(", ", genargNames));
}
else if (type.IsArray)
{
return String.Format("{0}[]", GetPrettyName(type.GetElementType()));
}
return type.Name;
}
}
public interface IFoo
{
ALogger TheALogger { get; }
}
public class Foo : IFoo
{
public ALogger TheALogger { get; private set; }
public Foo(ALogger aLogger) { TheALogger = aLogger; }
}
public class ALogger
{
public string LimitType { get; private set; }
public ALogger(string limitType)
{
LimitType = limitType;
}
}
public class ALoggerModule : Autofac.Module
{
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
{
registration.Preparing += (sender, args) =>
{
args.Parameters = args.Parameters.Union(new[]
{
new ResolvedParameter(
predicate: (p, i) => p.ParameterType == typeof(ALogger),
valueAccessor: (p, i) =>
{
Debug.WriteLine(String.Format("\tComponent.Activator.LimitType: {0}", args.Component.Activator.LimitType.GetPrettyName()));
Debug.WriteLine(String.Format("\tComponent.Target.Activator.LimitType: {0}", args.Component.Target.Activator.LimitType.GetPrettyName()));
return new ALogger(args.Component.Target.Activator.LimitType.GetPrettyName());
})
});
};
}
}
这是输出:
Resolving Meta<Lazy<IFoo>>[]
Component.Activator.LimitType: Meta<Lazy<IFoo>>[]
Component.Target.Activator.LimitType: Meta<Lazy<IFoo>>[]
Result is: Meta<Lazy<IFoo>>[]
Resolving Meta<Lazy<IFoo>>
Component.Activator.LimitType: Meta<Lazy<IFoo>>
Component.Target.Activator.LimitType: Foo
Result is: Foo
Done
答案 0 :(得分:0)
您想知道谁在解析ALogger
。
您的代码使用在基本类型准备时注入的自定义参数。使用此功能,您可以访问基本类型。
现在的问题是你要解决IEnumerable<IFoo>
,但由于CollectionRegistrationSource
的工作方式,你无法得到你想要的东西。
您可以尝试将解析上下文转换为IInstanceLookup
并获得您想要的内容:
protected override void AttachToComponentRegistration(
IComponentRegistry componentRegistry, IComponentRegistration registration)
{
registration.Preparing += (sender, args) =>
{
Console.WriteLine("Preparing {0}", registration.Activator
.LimitType
.GetPrettyName());
args.Parameters = args.Parameters.Union(new[]
{
new ResolvedParameter(
predicate: (pi, c) => pi.ParameterType == typeof(ALogger),
valueAccessor: (pi, c) =>
{
Parameter limitTypeParameter = null;
IInstanceLookup lookup = c as IInstanceLookup;
if(lookup != null)
{
String prettyName = lookup.ComponentRegistration
.Activator
.LimitType
.GetPrettyName();
limitTypeParameter = new NamedParameter("limitType", prettyName);
}
else
{
limitTypeParameter = new NamedParameter("limitType", null);
}
return c.Resolve<ALogger>(limitTypeParameter);
})
});
};
}