我正在尝试在unity中注册一个Generic Repository。我更喜欢在引导程序中使用反射来完成此操作。
我已经成功地实现并测试了这一点:
container.RegisterType(typeof(MyDll.Repositories.IRepository<>), typeof(MyDll.Repositories.Repository<>), "MyDllRepository");
然后解决:
var result = target.Resolve(typeof(My.Repositories.IRepository<MyClass>), "MyDllRepository");
效果很好。我不喜欢的是,我需要在引导程序解决方案中显式引用MyDll。
当我尝试在引导程序中使用反射自动注册存储库时,如下所示:
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; }
...
}
您基本上想要注册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>));