我在AutoMapper 4.2上,我无法弄清楚为什么我会收到此错误
Autofac.Core.Registration.ComponentNotRegisteredException 要求的服务 ' Navigator.ItemManagement.Data.MappingProfiles.ReportPreferenceReportUserIdsResolver' 尚未注册。要避免此异常,请注册a 组件提供服务,检查服务注册使用 IsRegistered(),或使用ResolveOptional()方法来解析 可选的依赖。
我的一个价值解析器出现了这个错误
public class ReportPreferenceProfile : Profile
{
protected override void Configure()
{
CreateMap<ReportPreference, ReportPreferenceSummaryDto>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Id))
.ForMember(d => d.Name, o => o.MapFrom(s => s.Name))
.ForMember(d => d.ReportUserIds, o => o.ResolveUsing<ReportPreferenceReportUserIdsResolver>());
}
}
public class ReportPreferenceReportUserIdsResolver : ValueResolver<IList<ReportUser>, IList<Guid>>
{
protected override IList<Guid> ResolveCore(IList<ReportUser> source)
{
return source.Select(r => r.UserId).ToList();
}
}
我已在我的Autofac模块中注册了这个
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ReportPreferenceReportUserIdsResolver>().As<IValueResolver>();
//register all profile classes in the calling assembly
var profiles =
from t in typeof(Navigator.ItemManagement.Data.MappingProfiles.PlaceMapperProfile).Assembly.GetTypes()
where typeof(Profile).IsAssignableFrom(t)
select (Profile)Activator.CreateInstance(t);
builder.Register(context => new MapperConfiguration(cfg =>
{
foreach (var profile in profiles)
{
cfg.AddProfile(profile);
}
})).AsSelf().SingleInstance();
builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve))
.As<IMapper>()
.SingleInstance();
}
更新1
我尝试了Lucian Bargaoanu的建议并取代了
builder.RegisterType<ReportPreferenceReportUserIdsResolver>().As<IValueResolver>();
与
builder.RegisterType<ReportPreferenceReportUserIdsResolver>().AsSelf();
现在我得到的错误是
System.ObjectDisposedException
此解析操作已经存在 结束。使用lambdas注册组件时, IComponentContext&#39; c&#39;无法存储lambda的参数。 相反,要么从&#39; c&#39;再次解析IComponentContext,要么解析 FUNC&LT;&GT;基于工厂从中创建后续组件。
映射类型:ReportPreference - &gt; IList
1 Navigator.ItemManagement.Core.ItemAggregate.ReportPreference -> System.Collections.Generic.IList
1 [[System.Guid,mscorlib, Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]目的地路径: ReportJobSummaryDto.Reports.Reports.Reports0 [0] .ReportUserIds0 [0]
来源价值: Navigator.ItemManagement.Core.ItemAggregate.ReportPreference ---&gt; AutoMapper.AutoMapperMappingException:
映射类型:ReportPreference - &gt; IList
1 Navigator.ItemManagement.Core.ItemAggregate.ReportPreference -> System.Collections.Generic.IList
1 [[System.Guid,mscorlib, Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]目的地路径: ReportJobSummaryDto.Reports.Reports.Reports0 [0] .ReportUserIds0 [0]
答案 0 :(得分:0)
遇到相同的问题后,我进行了问答。
正如@PeterRiesz在评论中提到的那样,由于您的IValueResolver
不需要任何依赖关系,因此,最简单的解决方案是更改连接值解析器的形式,以仅采用一个手动的新实例: / p>
o.ResolveUsing(new ReportPreferenceReportUserIdsResolver())
这不需要在Autofac容器中进行任何注册。
但是,您可能希望将服务注入其中,或者出于其他原因和可维护性而只想在Autofac中注册它。
首先,请确保您已将IValueResolver
类型注册为@LucianBargaoanu answered,并已在Autofac中注册:
builder.RegisterType<ReportPreferenceReportUserIdsResolver>().AsSelf();
我用与您相同的方式来定义AutoMapper注册,结果也得到了与上面显示的相同的错误。
经过大量研究和反复尝试以解决错误,我发现了StackOverflow Q&A,这使我朝着正确的方向前进。
您已经在设置AutoMapper的服务功能,以在此处用于解决依赖项:
builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve))
.As<IMapper>()
.SingleInstance();
但是,正如错误所指出的那样,上下文c
在实际执行时已经被处理掉了。解决此问题的方法是按如下方式重写lambda注册:
builder.Register(c =>
{
//This resolves a new context that can be used later.
var context = c.Resolve<IComponentContext>();
var config = context.Resolve<MapperConfiguration>();
return config.CreateMapper(context.Resolve);
})
.As<IMapper>()
.SingleInstance();
还存在注册服务解析器的其他方法。您可以在MapperConfiguration注册中代替,如下所示:
builder.Register(c =>
{
//Again, we must store a new instance of a component context for later use.
var context = c.Resolve<IComponentContext>();
var profiles = c.Resolve<IEnumerable<Profile>>();
return new MapperConfiguration(x =>
{
foreach (var profile in profiles)
{
x.AddProfile(profile);
}
//Registering the service resolver method here.
x.ConstructServicesUsing(context.Resolve);
});
})
.SingleInstance()
.AsSelf();
这些似乎都是等效的。我认为后者个人比较干净。
这里要解决的问题是,因为在Lambda实际执行之前就将处理传入的实例,所以需要在顶级Lambda中解析新的上下文。
答案 1 :(得分:-1)
尝试
builder.RegisterType<ReportPreferenceReportUserIdsResolver>().AsSelf();