using System;
using Castle.Windsor;
using Castle.MicroKernel.Registration;
using System.Reflection;
using Castle.MicroKernel.Resolvers.SpecializedResolvers;
namespace Windsor
{
class MainClass
{
public static void Main (string[] args)
{
var container = new WindsorContainer ();
container.Register (Component.For (typeof(IIface<, >)).ImplementedBy (typeof(HandlerImpl<, >)));
//container.Register (Component.For (typeof(IIface<, >)).ImplementedBy(typeof(Impl2)));
container.Kernel.Resolver.AddSubResolver (new ArrayResolver (container.Kernel));
var normal = container.ResolveAll<IIface<Impl2, Stub>> ();
var ex = container.ResolveAll<IIface<Impl1, Stub>> ();
//var qwe = new HandlerImpl<Impl1, Stub> ();
Console.WriteLine("Hello World!");
}
}
public class Base {}
public class Stub {}
public interface AdditionalIface
{
}
public interface IIface<T1, T2> where T1 : Base where T2 : class
{
T1 Command { get; set; }
}
public class HandlerImpl<T1, T2> : IIface<T1, T2> where T1 : Base, AdditionalIface where T2 : class
{
public T1 Command { get; set; }
}
public class Impl1 : Base
{
}
public class Impl2 : Base, AdditionalIface
{
}
}
所以,现在,如果我喜欢这样的话:
var normal = container.ResolveAll<IIface<Impl2, Stub>> (); // this works ok
var ex = container.ResolveAll<IIface<Impl1, Stub>> (); // this throws exception abou not fullfilled constraints
// instead i want it just show no resolved implementations
有没有办法按照我的意愿来完成这项工作?
答案 0 :(得分:3)
实际上这似乎是温莎代码中的一个错误。
现在已修复
答案 1 :(得分:1)
如果您正常注入事物(即使用ArrayResolver而不是直接调用ResolveAll()
),您可以使用仅适用于此类型的自定义数组解析器(或针对具有此问题的类型)解决此问题:< / p>
public class CustomArrayResolver : ISubDependencyResolver {
private readonly IKernel kernel;
private readonly Type serviceTypeDefinition;
public CustomArrayResolver(IKernel kernel, Type serviceTypeDefinition) {
this.kernel = kernel;
this.serviceTypeDefinition = serviceTypeDefinition;
}
private bool MatchesConstraints(Type service, Type impl) {
try {
impl.MakeGenericType(service.GetGenericArguments());
return true;
} catch (ArgumentException) {
return false;
}
}
public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver,
ComponentModel model,
DependencyModel dependency) {
var service = dependency.TargetType.GetElementType();
var handlers = kernel.GetAssignableHandlers(service);
var components = handlers
.Where(h => h.CurrentState == HandlerState.Valid)
.Where(h => MatchesConstraints(service, h.ComponentModel.Implementation))
.Select(h => h.Resolve(context, contextHandlerResolver, model, dependency))
.ToArray();
var r = Array.CreateInstance(service, components.Length);
components.CopyTo(r, 0);
return r;
}
public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver,
ComponentModel model,
DependencyModel dependency) {
return dependency.TargetType != null &&
dependency.TargetType.IsArray &&
kernel.HasComponent(dependency.TargetType.GetElementType()) &&
dependency.TargetType.GetElementType().IsGenericType &&
dependency.TargetType.GetElementType().GetGenericTypeDefinition() == serviceTypeDefinition;
}
}
在标准ArrayResolver之前注册:
container.Kernel.Resolver.AddSubResolver(new CustomArrayResolver(container.Kernel, typeof(IIface<,>)));