城堡 - 没有支持服务的组件 - 使用泛型参数流畅地注册和解析泛型
本文关键字:泛型 参数 注册 和解 支持 服务 城堡 组件 | 更新日期: 2023-09-27 18:36:37
如果我使用一个接一个的组件注册,一切都可以解决..我的问题是流畅的注册,有什么想法吗?
例
public class MyFilter:Filter {}
public class MyEntity:Entity {}
public class ReadCommandHandler<TEntity,TFilter> : ICommandHandler<IReadCommand<TFilter>, IEnumerable<TEntity>> where TEntity : Entity where TFilter : Filter
安装
container.Register(Types.FromThisAssembly().BasedOn(typeof(ICommandHandler<,>)).WithService.AllInterfaces());
这将导致(调试器视图)
ReadCommandHandler<···TFilter·>/ICommandHandler
所以看起来没关系..但是如果我尝试过这个
var biz = container.Resolve(typeof(ICommandHandler<IReadCommand<MyFilter>,IEnumerable<MyEntity>>))
或者这个
var biz = container.Resolve(typeof(ICommandHandler<IReadCommand<Filter>,IEnumerable<Entity>>))
结果是"没有支持服务的组件"
这是怎么回事?
好的.. 作为一种可能的方法,我用 IGenericImplementationMatchingStrategy "解决"了这个问题
设置和解决:
var container = new WindsorContainer();
container.Register(
Types.FromAssemblyContaining(typeof(ReadCommandHandler<,>)).BasedOn(typeof(ICommandHandler<,>))
.If(p => !p.IsInterface)
.WithServiceBase()
.Configure(
c => c.ExtendedProperties(
Property.ForKey(Castle.Core.Internal.Constants.GenericImplementationMatchingStrategy)
.Eq(new GenericImplementationMatchingStrategy()))));
var biz = container.Resolve(typeof(ICommandHandler<IReadCommand<MyFilter>, IEnumerable<MyEntity>>));
通用战略实施
public class GenericImplementationMatchingStrategy : IGenericImplementationMatchingStrategy
{
public static ConcurrentDictionary<string, Type[]> dicStrategyCommandHandler = new ConcurrentDictionary<string, Type[]>();
public Type[] GetGenericArguments(ComponentModel model, CreationContext context)
{
return dicStrategyCommandHandler.GetOrAdd(context.RequestedType.FullName, (key) =>
{
if (context.RequestedType.GetGenericTypeDefinition() == typeof(ICommandHandler<,>))
{
var service = model.Implementation.GetInterfaces().Where(p => { return p.Name == context.RequestedType.Name; }).FirstOrDefault(); // model.Implementation.GetInterfaces()[0];
if (service != null)
{
List<Type> types = new List<Type>();
foreach (var item in model.Implementation.GetGenericArguments())
{
var name = item.Name;
var type = serviceGetType(name, service, context.RequestedType);
types.Add(type);
}
return types.ToArray();
}
}
return null;
}
);
}
private Type serviceGetType(string name, Type service, Type requestedType)
{
var args = service.GetGenericArguments().ToArray();
var argsRequested = requestedType.GetGenericArguments().ToArray();
for (int i=0;i<args.Count();i++ )
{
Type itemDecla = args[i];
Type itemRequested = argsRequested[i];
if (itemDecla.Name == name)
return itemRequested;
else
{
var recur = serviceGetType(name, itemDecla, itemRequested);
if (recur != null) return recur;
}
}
return null;
}
}
你怎么看..更好的东西?
我唯一想知道的问题是,为什么如果我的组件生活方式是单例的,每次我调用 Resolve(..) 时,resolve 方法都会调用 GenericImplementationMatchingStrategy。