Unity的“按惯例注册”可以解决抽象类吗?

时间:2014-06-13 12:29:56

标签: c# interface unity-container abstract

我有一个通用的存储库通用接口。

我有一个通用的抽象类,它继承自通用泛型接口,并实现了一些处理WCF服务的魔术反射方法。

然后,我为每个特定的存储库提供了非通用的非通用抽象类。这些抽象类具有我想用Unity注入其各自服务的实现。

Unity有一种花哨的"按惯例注册"注册接口的功能,这非常好用......

        var container = new UnityContainer();

        container.RegisterTypes(
            AllClasses.FromLoadedAssemblies(),
            WithMappings.FromAllInterfaces,
            WithName.Default,
            WithLifetime.PerResolve);

我的问题是,我如何注册我的抽象类和每个存储库特定存储库的实现,比如接口?

这在CastleWindsor和StructureMap中似乎是可能的,所以我有点不知道为什么RegisterTypes中的Enum不包含抽象类...

我还尝试手动注册它,想到创建一个反射类来扫描应用程序并为我连线,如果团结不能......我试着这样做:

        container.RegisterType<BaseToolRepository, ToolRepository>();
        container.RegisterType<BaseGenericRepository<ToolServiceClient,Tool>, BaseToolRepository>();
        container.RegisterType<IGenericRepository<Tool>, BaseGenericRepository<ToolServiceClient, Tool>>();

但它无法解决。我做错了什么吗? 描述摘要
- ToolRepository是实现,
- BaseToolRepository是第一个特定的抽象类。
- BaseGenericRepsoitory是Generic Abstract类,包含反射逻辑和
- IGenericRepository是底部的接口....

1 个答案:

答案 0 :(得分:2)

这取决于您要解决的问题,但如果将所有基本类型映射到具体类型,则可以实现所有目标。您目前正在告诉Unity将IGenericRepository映射到抽象类,因此如果您尝试解析该接口,Unity会尝试创建抽象类的实例并失败。

注册此注册码......

container.RegisterType<BaseToolRepository, ToolRepository>();
container.RegisterType<BaseGenericRepository<ToolServiceClient, Tool>, ToolRepository>();
container.RegisterType<IGenericRepository<Tool>, ToolRepository>();

然后所有这些结果都应该有用......

container.Resolve<ToolRepository>();
container.Resolve<BaseToolRepository>();
container.Resolve<BaseGenericRepository<ToolServiceClient, Tool>>();
container.Resolve<IGenericRepository<Tool>>();

此外,这里有一些自定义映射,您可以按惯例注册...

public static class WithCustomMappings
{
    public static Func<Type, IEnumerable<Type>> AggregateMappings(params Func<Type, IEnumerable<Type>>[] mappings)
    {
        return type =>
        {
            var mappedTypes = new List<Type>();
            foreach (var mapping in mappings)
                mappedTypes.AddRange(mapping(type));
            return mappedTypes.Distinct();
        };
    }

    public static Func<Type, IEnumerable<Type>> FromAllAbstractBaseClasses 
    {
        get
        {
            return type =>
            {
                var abstractBaseTypes = new List<Type>();
                var baseType = type.BaseType;
                while (baseType != null)
                {
                    if (baseType.IsAbstract)
                        abstractBaseTypes.Add(baseType);
                    baseType = baseType.BaseType;
                }
                return abstractBaseTypes;
            };
        }
    }
}

使用它......

container.RegisterTypes(
    AllClasses.FromLoadedAssemblies(),
    WithCustomMappings.AggregateMappings(WithMappings.FromAllInterfaces, WithCustomMappings.FromAllAbstractBaseClasses),
    WithName.Default,
    WithLifetime.PerResolve);