使用Unity中的反射注册通用类型

时间:2015-02-10 18:04:36

标签: c# generics unity-container

我正在尝试统一注册通用存储库。我更喜欢使用反射在引导程序中执行此操作。

我已经成功实施并测试了这个:

container.RegisterType(typeof(MyDll.Repositories.IRepository<>), typeof(MyDll.Repositories.Repository<>), "MyDllRepository");

然后解决:

var result = target.Resolve(typeof(My.Repositories.IRepository<MyClass>), "MyDllRepository");

效果很好。我不喜欢的是我需要在Bootstrapper解决方案中明确引用MyDll。

当我尝试使用Bootstrapper中的反射自动注册存储库时,如下所示:

private void RegisterDlls(String assembly)
    {
        var currentAssembly = Assembly.LoadFrom(assembly);
        var assemblyTypes = currentAssembly.GetTypes();

        var baseName = GetBaseName(currentAssembly.FullName);

        foreach (var assemblyType in assemblyTypes)
        {
            if (assemblyType.IsInterface)
            {
                continue;
            }

            if (assemblyType.FullName.EndsWith("Service"))
            {
                foreach (var requiredInterface in assemblyType.GetInterfaces())
                {
                    if (requiredInterface.FullName.EndsWith("Service"))
                    {
                        var typeFrom = assemblyType.GetInterface(requiredInterface.Name);
                        var typeTo = assemblyType;
                        RegisterType(typeFrom, typeTo, true, typeTo.Name);
                    }
                }
            }

        if (assemblyType.Namespace.EndsWith("Repositories"))
        {
        foreach (var requiredInterface in assemblyType.GetInterfaces())
        {
        if (requiredInterface.Namespace.EndsWith("Repositories"))
                 {
        var typeFrom = assemblyType.GetInterface(requiredInterface.Name);
        var typeTo = assemblyType;
        string registerName = String.Concat(baseName, "Repository");
        _container.RegisterType(typeFrom, typeTo, registerName);
                }
    }
    }

解决时我得到例外:

用户代码未处理Microsoft.Practices.Unity.ResolutionFailedException 消息=依赖项的解析失败,type =“MyDll.Repositories.IRepository 1[MyDll.Models.MyClass]", name = "MyDllRepository". Exception occurred while: while resolving. Exception is: InvalidOperationException - The current type, MyDll.Repositories.IRepository 1 [MyDll.Models.MyClass],是一个接口,无法构造。

任何想法?

MyDll.Repositories.Repository类:

    public class Repository<TModel> : IRepository<TModel> where TModel : class, IModel
{
    [Dependency("MyDllDataProvider")]
    public IMyDllDataProvider _dataProvider { get; set; }
    ...
}

1 个答案:

答案 0 :(得分:0)

您基本上想要注册IRepository<>界面的任何实现吗?

Unity 3.x中有一种方法可用于此类基于约定的注册。在容器上,您有一个方法RegisterTypes,它采用不同的参数,例如要扫描的程序集,要查找的接口等......

所以我认为这正是你应该做的,并且它与泛型类型完全一致。

只是一个简单的示例,它将扫描“bin”目录中的所有程序集或任何基本路径...并过滤类型名称。

container.RegisterTypes(
   AllClasses.FromAssembliesInBasePath(), 
   (t) => t.Name.EndsWith("Service") ? new[] { t } : new Type[] { },
   WithName.TypeName);

您可以完全自定义每个过滤器或说明,这些只是简单的Func方法,可以轻松自定义。

之后你应该可以通过例如

来解决它们
container.ResolveAll(typeof(IRepository<MyClass>));