我正在尝试统一注册通用存储库。我更喜欢使用反射在引导程序中执行此操作。
我已经成功实施并测试了这个:
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; }
...
}
答案 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>));