繁体   English   中英

Unity层次结构构造函数注入

[英]Unity Hierarchy Constructor Injection

我在理解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 ,我更改了您提供IDataContextAsyncIUnitOfWorkAsync 基本上,您使用的方式是,以错误的顺序提供参数。


附带说明,您无需为每个注册都提供一个名称。 仅在要多次注册同一接口时才需要提供名称,即使在这种情况下,您仍然可以具有默认的未命名注册。

另外,您无需手动告诉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具有一个构造函数,该构造函数接受IDataContextAsyncIUnitOfWorkAsync ,并为它们提供实例,因为他知道如何解析它们。 这些接口的默认注册将分别解析为类Zeus (带有构造函数参数Zeus,可能是连接字符串?)和UnitOfWork类的实例。

希望有帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM