我在理解Unity如何解析层次结构树下方对象的引用以及如何注入相关构造函数方面遇到困难。
目前,我已将容器配置为:
container
.RegisterType<IDataContextAsync, Zeus>("ZeusLive", new PerRequestLifetimeManager(), new InjectionConstructor("ZeusLive"))
.RegisterType<IDataContextAsync, Zeus>("Zeus", new PerRequestLifetimeManager(), new InjectionConstructor("Zeus"))
.RegisterType<IUnitOfWorkAsync, UnitOfWork>("ZeusUnitOfWork", new InjectionConstructor(new ResolvedParameter<IDataContextAsync>("Zeus")))
.RegisterType<IRepositoryAsync<cd_Job>, Repository<cd_Job>>(new InjectionConstructor(new ResolvedParameter<IUnitOfWorkAsync>("ZeusUnitOfWork"), new ResolvedParameter<IDataContextAsync>("Zeus")));
(我使用的是通用的工作单位和存储库模式(https://genericunitofworkandrepositories.codeplex.com/))
问题在于此行:
.RegisterType<IRepositoryAsync<cd_Job>, Repository<cd_Job>>(new InjectionConstructor(new ResolvedParameter<IUnitOfWorkAsync>("ZeusUnitOfWork"), new ResolvedParameter<IDataContextAsync>("Zeus")))
我收到以下错误:
The type Repository.Pattern.Ef6.Repository`1[[DataRepository.Models.cd_Job, DataRepository, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] does not have a constructor that takes the parameters (IUnitOfWorkAsync, IDataContextAsync)
Repository类的构造函数如下:
public Repository(IDataContextAsync context, IUnitOfWorkAsync unitOfWork)
{
_context = context;
_unitOfWork = unitOfWork;
// Temporarily for FakeDbContext, Unit Test and Fakes
var dbContext = context as DbContext;
if (dbContext != null)
{
_dbSet = dbContext.Set<TEntity>();
}
else
{
var fakeContext = context as FakeDbContext;
if (fakeContext != null)
{
_dbSet = fakeContext.Set<TEntity>();
}
}
}
我怀疑我的问题是我不完全了解如何解决层次结构引用,并且我的错误很明显,但是我仍在学习,因此希望能获得一些指导
您需要InjectionConstructor
按照在构造函数中定义的顺序提供参数的参数。
您的构造函数的定义如下:
public Repository(IDataContextAsync context, IUnitOfWorkAsync unitOfWork)
{
}
因此,您需要像这样注册:
.RegisterType<IRepositoryAsync<cd_Job>, Repository<cd_Job>>(
new InjectionConstructor(
new ResolvedParameter<IDataContextAsync>("Zeus"),
new ResolvedParameter<IUnitOfWorkAsync>("ZeusUnitOfWork")))
如您所见,我已经更改了您提供IDataContextAsync
和的顺序IUnitOfWorkAsync
。基本上,您使用的方式是,您以错误的顺序提供了参数。
附带说明,您无需为每个注册都提供一个名称。仅在要多次注册同一接口时才需要提供名称,即使在这种情况下,您仍然可以使用默认的未命名注册。
另外,您无需手动告诉Unity如何解析每个构造函数参数,因为默认情况下他足够聪明来解析它(如果它知道如何解析它)。
因此,您的示例可以简化为:
container
.RegisterType<IDataContextAsync, Zeus>("ZeusLive", new PerRequestLifetimeManager(), new InjectionConstructor("ZeusLive"))
.RegisterType<IDataContextAsync, Zeus>(new PerRequestLifetimeManager(), new InjectionConstructor("Zeus"))
.RegisterType<IUnitOfWorkAsync, UnitOfWork>()
.RegisterType<IRepositoryAsync<cd_Job>, Repository<cd_Job>>();
Unity非常聪明,可以意识到Repository
有一个构造函数采用IDataContextAsync
和IUnitOfWorkAsync
,并为他提供实例,因为他知道如何解析它们。这些接口的默认注册将分别解析为类的实例Zeus
(使用构造函数参数Zeus,可能是连接字符串?)UnitOfWork
。
希望有帮助!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句