ComponentNotRegisteredException 使用 AutoMapper 与 Autofac

huangapple go评论121阅读模式
英文:

ComponentNotRegisteredException using AutoMapper with Autofac

问题

I'm getting an error when attempting to resolve an AutoMapper.IMapper instance:

Autofac.Core.Registration.ComponentNotRegisteredException: The requested service 'System.Object' has not been registered.

Here's my registration:

Builder.Register(Function(Context)
                   Return New MapperConfiguration(Sub(Config)
                                                    Config.AddProfile(Of MappingProfile)()
                                                  End Sub).CreateMapper
                 End Function).As(Of IMapper)()

...and here's the resolution:

Using oScope As ILifetimeScope = Me.Container.BeginLifetimeScope
  oMapper = oScope.Resolve(Of IMapper)
End Using

Here's my mapping profile:

Public Class MappingProfile
  Inherits Profile

  Public Sub New()
    Me.CreateMap(Of Dto.Release, Model.Release)()
    Me.CreateMap(Of Model.Release, Dto.Release)()
  End Sub
End Class

I've tried suggestions from these answers and more, but none of them result in anything but even more complex errors:

...as well as this blog post.

I've found many Q&As here on using AutoMapper with Autofac, a lot of them with accepted answers, but none of them seem to apply to my situation (at least that I'm able to understand/recognize). But then again, discussions here on using the two together are pretty dated. Not much under the context of the latest versions is showing up in searches.

I did notice a pattern in some of the accepted answers, and that would be to pass a Func(Of Object, IMapper) to the Builder.Register() function. Perhaps that's where the error originates: the parameter of type Object of that Func.

It's worth noting that the Context parameter here—for me at least—is always of type System.Object:

Builder.Register(Function(Context)
                 End Function)

So I'm not seeing how folks are getting code like this to work:

builder.Register(c =>
{
  //This resolves a new context that can be used later.
  var context = c.Resolve<IComponentContext>();
})

Obviously there is no Resolve<IComponentContext>() function on System.Object. Has something changed in the Autofac API with regard to the Builder.Register() function since those answers were written?

Assuming usage of the latest versions of both packages, how can I successfully register and resolve an AutoMapper.IMapper instance?

英文:

I'm getting an error when attempting to resolve an AutoMapper.IMapper instance:

> Autofac.Core.Registration.ComponentNotRegisteredException : The requested service 'System.Object' has not been registered.

Here's my registration:

Builder.Register(Function(Context)
                   Return New MapperConfiguration(Sub(Config)
                                                    Config.AddProfile(Of MappingProfile)()
                                                  End Sub).CreateMapper
                 End Function).As(Of IMapper)()

...and here's the resolution:

Using oScope As ILifetimeScope = Me.Container.BeginLifetimeScope
  oMapper = oScope.Resolve(Of IMapper)
End Using

Here's my mapping profile:

Public Class MappingProfile
  Inherits Profile

  Public Sub New()
    Me.CreateMap(Of Dto.Release, Model.Release)()
    Me.CreateMap(Of Model.Release, Dto.Release)()
  End Sub
End Class

I've tried suggestions from these answers and more, but none of them result in anything but even more complex errors:

...as well as this blog post.

I've found many Q&As here on using AutoMapper with Autofac, a lot of them with accepted answers, but none of them seem to apply to my situation (at least that I'm able to understand/recognize). But then again, discussions here on using the two together are pretty dated. Not much under the context of the latest versions is showing up in searches.

I did notice a pattern in some of the accepted answers, and that would be to pass a Func(Of Object, IMapper) to the Builder.Register() function. Perhaps that's where the error originates: the parameter of type Object of that Func.

It's worth noting that the Context parameter here—for me at least—is always of type System.Object:

Builder.Register(Function(Context)
                 End Function)

So I'm not seeing how folks are getting code like this to work:

builder.Register(c =&gt;
{
  //This resolves a new context that can be used later.
  var context = c.Resolve&lt;IComponentContext&gt;();
})

Obviously there is no Resolve&lt;IComponentContext&gt;() function on System.Object. Has something changed in the Autofac API with regard to the Builder.Register() function since those answers were written?

Assuming usage of the latest versions of both packages, how can I successfully register and resolve an AutoMapper.IMapper instance?

答案1

得分: 0

The fix is to cast the incoming Context parameter as IComponentContext. I'm not sure why this is required in VB.NET and not C#, but so be it. (If you happen to know and would like to chime in on the comments, I'd love to hear from you.)

Converted from the full working example discussed here and published here, the final solution is:

Dim oContext As IComponentContext
Dim oConfig As MapperConfiguration
Dim oAction As Action(Of IMapperConfigurationExpression)

oAction = Sub(Config) Config.AddProfile(Of MappingProfile)()

Builder.Register(Function(Context As IComponentContext)
          Return New MapperConfiguration(oAction)
        End Function).AsSelf.SingleInstance()

Builder.Register(Function(Context As IComponentContext)
          oContext = Context.Resolve(Of IComponentContext)
          oConfig = oContext.Resolve(Of MapperConfiguration)

          Return oConfig.CreateMapper(AddressOf oContext.Resolve)
        End Function).As(Of IMapper).InstancePerLifetimeScope()

With this slight variation, component resolution now works.

英文:

The fix is to cast the incoming Context parameter as IComponentContext. I'm not sure why this is required in VB.NET and not C#, but so be it. (If you happen to know and would like to chime in on the comments, I'd love to hear from you.)

Converted from the full working example discussed here and published here, the final solution is:

Dim oContext As IComponentContext
Dim oConfig As MapperConfiguration
Dim oAction As Action(Of IMapperConfigurationExpression)

oAction = Sub(Config) Config.AddProfile(Of MappingProfile)()

Builder.Register(Function(Context As IComponentContext)
          Return New MapperConfiguration(oAction)
        End Function).AsSelf.SingleInstance()

Builder.Register(Function(Context As IComponentContext)
          oContext = Context.Resolve(Of IComponentContext)
          oConfig = oContext.Resolve(Of MapperConfiguration)

          Return oConfig.CreateMapper(AddressOf oContext.Resolve)
        End Function).As(Of IMapper).InstancePerLifetimeScope()

With this slight variation, component resolution now works.

huangapple
  • 本文由 发表于 2023年4月11日 13:06:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75982552.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定