城堡 - 没有支持服务的组件 - 使用泛型参数流畅地注册和解析泛型

本文关键字:泛型 参数 注册 和解 支持 服务 城堡 组件 | 更新日期: 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<·TFilter·>, IEnumerable<·泰恩蒂·>>

所以看起来没关系..但是如果我尝试过这个

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。