Autofac:如何注册/解析构造函数以抽象类型作为参数的类型?

问题描述 投票:0回答:0

我有两个继承自抽象类的具体类:

Public Class UpdateCommand
  Inherits BaseCommand
  Implements IUpdateCommand

  Public Sub New(Root As DirectoryInfo)
    MyBase.New(Root)
  End Sub
End Class

Public Class CleanCommand
  Inherits BaseCommand
  Implements ICleanCommand

  Public Sub New(Root As DirectoryInfo)
    MyBase.New(Root)
  End Sub
End Class

Public MustInherit Class BaseCommand
  Implements IBaseCommand

  Public Sub New(Root As DirectoryInfo)
    Me.Root = Root
  End Sub

  Protected ReadOnly Property Root As DirectoryInfo Implements IBaseCommand.Root
End Class

...然后我在他们旁边有这堂课:

Public Class Downloader
  Implements IDownloader

  Public Sub New(Command As IBaseCommand)
    Me.Root = Command.Root
  End Sub

  Private ReadOnly Root As DirectoryInfo Implements IDownloader.Root
End Class

接口的构造类似:

Public Interface IUpdateCommand
  Inherits IBaseCommand
End Interface

Public Interface ICleanCommand
  Inherits IBaseCommand
End Interface

Public Interface IBaseCommand
  ReadOnly Property Root As DirectoryInfo
End Interface

Public Interface IDownloader
  ReadOnly Property Root As DirectoryInfo
End Interface

我的注册是这样的:

oRoot = New DirectoryInfo(Options.Root)
oParameters = New List(Of Parameter) From {
  New NamedParameter(NameOf(Options.Root), oRoot)
}

oBuilder = New ContainerBuilder
oBuilder.RegisterType(Of UpdateCommand).As(Of IUpdateCommand).WithParameters(oParameters)
oBuilder.RegisterType(Of CleanCommand).As(Of ICleanCommand).WithParameters(oParameters)
oBuilder.RegisterType(Of Downloader).As(Of IDownloader)()

...这就是我解决它们的方法:

Dim oUpdateCommand As IUpdateCommand
Dim oCleanCommand As ICleanCommand

Using oScope As ILifetimeScope = Container.BeginLifetimeScope
  oUpdateCommand = oScope.Resolve(Of IUpdateCommand)
  oCleanCommand = oScope.Resolve(Of ICleanCommand)
  oDownloader = oScope.Resolve(Of IDownloader)
End Using

这是我尝试解决时遇到的错误

oDownloader

在类型“VsLayout.Downloader”上找到的构造函数都不能用可用的服务和参数调用: 无法解析构造函数“Void .ctor(VsLayout.IBaseCommand)”的参数“VsLayout.IBaseCommand Command”。

有关更多信息,请参阅https://autofac.rtfd.io/help/no-constructors-bindable

不幸的是,文档没有解决这种情况。

我尝试稍微更改我的注册,指定

IBaseCommand
而不是
IUpdateCommand
/
ICleanCommand
:

oBuilder = New ContainerBuilder
oBuilder.RegisterType(Of UpdateCommand).As(Of IBaseCommand).WithParameters(oParameters)
oBuilder.RegisterType(Of CleanCommand).As(Of IBaseCommand).WithParameters(oParameters)
oBuilder.RegisterType(Of Downloader).As(Of IDownloader)()

...但是在解析时会导致不同的错误:

Autofac.Core.Registration.ComponentNotRegisteredException HResult=0x80131500 Message=请求的服务“VsLayout.IUpdateCommand”尚未注册。要避免此异常,请注册一个组件以提供服务,使用 IsRegistered() 检查服务注册,或使用 ResolveOptional() 方法解析可选依赖项。

有关更多信息,请参阅https://autofac.rtfd.io/help/service-not-registered

同样,文档不涵盖此特定场景。

然后我尝试稍微改变一下分辨率:

Dim oUpdateCommand As IUpdateCommand
Dim oCleanCommand As ICleanCommand
Dim oDownloader As IDownloader

Using oScope As ILifetimeScope = Container.BeginLifetimeScope
  oUpdateCommand = oScope.Resolve(Of IBaseCommand)
  oCleanCommand = oScope.Resolve(Of IBaseCommand)
  oDownloader = oScope.Resolve(Of IDownloader)
End Using

那是行不通的,因为

IBaseCommand
对象不能转换为
IUpdateCommand
。当然,我可以将
oUploadCommand
声明为
IBaseCommand
,这样就可以运行,但是
IUpdateCommand
最终将具有我需要的独特属性。

最后,

Downloader
类必须以一个抽象作为参数,因为
UpdateCommand
ClearCommand
都会用到它。

所以我们卡住了吗?我们如何使用具有继承性的 Autofac?

inheritance dependency-injection abstract-class autofac
© www.soinside.com 2019 - 2024. All rights reserved.