C# 统一解析所有泛型接口

C# 统一解析所有泛型接口,c#,generics,unity-container,ioc-container,C#,Generics,Unity Container,Ioc Container,我使用的是Unity IoC,我想注册非泛型类到泛型接口的映射。之后,我想使用ResolveAll方法来检索与泛型接口关联的所有注册。 这是示例代码: interface ISample<out T> { } class Ca : ISample<int> { } class Cb : ISample<string> { } class Program { static void Main(string[] args) {

我使用的是Unity IoC,我想注册非泛型类到泛型接口的映射。之后,我想使用ResolveAll方法来检索与泛型接口关联的所有注册。 这是示例代码:

interface ISample<out T> { }
class Ca : ISample<int> { }
class Cb : ISample<string> { }

class Program
{
    static void Main(string[] args)
    {

        var container = new UnityContainer();
        container.RegisterType<ISample<int>,Ca>();
        container.RegisterType<ISample<string>, Cb>();

        var classList = container.ResolveAll(typeof(ISample<>));
    }
}
ISample不是Unity的有效类型;您不能注册它,也不能使用ResolveAll获取使用它的所有类型。如果您查看ResolveAll返回的内容,这有助于显示问题。在这种情况下,它将返回一个无效的IEnumerable>

我不太确定您想做什么,所以我不知道建议尝试什么。

ResolveAll用于查找特定类型的所有命名解析,它与您正在使用的开放泛型不一样。要想得到你想要的,你需要去做

var registrations = container.Registrations
                   .Where(x => x.RegisteredType.IsGenericType && 
                               x.RegisteredType.GetGenericTypeDefinition() == typeof(ISample<>))
                   .ToList();
唯一可以同时保存ISample和ISample的列表类型是object。一份清单是行不通的。如果将接口重写为

interface ISample { }
interface ISample<out T> : ISample { }
顺便说一句,为了明确内置ResolveAll在做什么,它基本上是

public IEnumerable<object> ResolveAll(Type t, params ResolverOverride[] resolverOverrides)
{
    var registrations = this.Registrations.Where(x => x.RegisteredType == t);
    foreach (var registration in registrations)
    {
        if(registration.Name != null)
            yield return this.Resolve(registration.RegisteredType, registration.Name, resolverOverrides)
    }
}

我已经完成了创建以下ExtensionMethod的任务

public static IEnumerable<object> ResolveAllOpenGeneric(this IUnityContainer container, Type openGenericType)
{
    if (!openGenericType.IsGenericTypeDefinition)
        throw new ArgumentNullException("argument must be open generic type");

    return container.Registrations.Where(c =>
                                            c.RegisteredType.IsGenericType
                                            && c.RegisteredType.GetGenericTypeDefinition() == openGenericType
                                        )
                                        .Select(r =>
                                                    container.Resolve(r.RegisteredType, r.Name)
                                        );
}

public static IEnumerable<T> ResolveAllOpenGeneric<T>(this IUnityContainer container, Type openGenericType)
{
    if (!openGenericType.IsGenericTypeDefinition)
        throw new ArgumentNullException("argument must be open generic type");

    return container.Registrations.Where(c =>
                                             c.RegisteredType.IsGenericType
                                             && c.RegisteredType.GetGenericTypeDefinition() == openGenericType
                                         )
                                         .Select(r =>
                                                     (T)container.Resolve(r.RegisteredType, r.Name)
                                         );
}

错误是什么?你能发布完整的消息和堆栈跟踪吗?请不要添加感谢和其他与问题没有直接关系的文本,如新到C,网站,。。。回答问题。如果你觉得感谢对你的问题很重要——请先讨论一下,但是先考虑阅读。同时请确保添加确切的错误信息,我已经删除了具体的问题来帮助我从帖子中提问。旁注:ISample经常被称为open-generic,它可能会帮助您搜索答案,而且我认为您不能随心所欲。根据您的提示,我已经发布了一个扩展方法,您能给我一些建议吗?
interface ISample { }
interface ISample<out T> : ISample { }
var registrations = container.Registrations
                   .Where(x => typeof(ISample).IsAssignableFrom(x.RegisteredType));

var classList = new List<ISample>();
foreach (var registration in registrations)
{
    var classObject = container.Resolve(registration.RegisteredType, registration.Name);
    classList.Add((ISample)classObject);
}
public IEnumerable<object> ResolveAll(Type t, params ResolverOverride[] resolverOverrides)
{
    var registrations = this.Registrations.Where(x => x.RegisteredType == t);
    foreach (var registration in registrations)
    {
        if(registration.Name != null)
            yield return this.Resolve(registration.RegisteredType, registration.Name, resolverOverrides)
    }
}
public static IEnumerable<object> ResolveAllOpenGeneric(this IUnityContainer container, Type openGenericType)
{
    if (!openGenericType.IsGenericTypeDefinition)
        throw new ArgumentNullException("argument must be open generic type");

    return container.Registrations.Where(c =>
                                            c.RegisteredType.IsGenericType
                                            && c.RegisteredType.GetGenericTypeDefinition() == openGenericType
                                        )
                                        .Select(r =>
                                                    container.Resolve(r.RegisteredType, r.Name)
                                        );
}

public static IEnumerable<T> ResolveAllOpenGeneric<T>(this IUnityContainer container, Type openGenericType)
{
    if (!openGenericType.IsGenericTypeDefinition)
        throw new ArgumentNullException("argument must be open generic type");

    return container.Registrations.Where(c =>
                                             c.RegisteredType.IsGenericType
                                             && c.RegisteredType.GetGenericTypeDefinition() == openGenericType
                                         )
                                         .Select(r =>
                                                     (T)container.Resolve(r.RegisteredType, r.Name)
                                         );
}