我经历了几个问题,但无法正确解决。
[尝试使用AutoMapper 7.0时,出现Mapper not initialized
异常-尽管我认为我的问题与AutoMapper不相关,但与我尝试向WCF注册服务的方式有关。
我关注了this文章,并为我的AutoMapper创建了ServiceBehavior:
public sealed class AutomapServiceBehavior : Attribute, IServiceBehavior
{
public AutomapServiceBehavior()
{
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
AutomapBootstrap.InitializeMap();
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
}
public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
}
}
然后向AutomapBootstrap.InitializeMap()添加一个断点(看起来像这样):
public class AutomapBootstrap
{
public static void InitializeMap()
{
//BREAKPOINT ADDED HERE
var config = new MapperConfiguration(cfg =>
cfg.CreateMap<ClassA, ClassB>()
);
var mapper = new Mapper(config);
}
}
我以为应用程序应该在启动期间在我的断点处停止,但不是这样。我想念什么?
首先,您需要确保将注释添加到服务中以首先调用行为
[AutomapServiceBehavior] <-------
[ServiceErrorBehavior(typeof(ElmahErrorHandler))]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class DVDService : IDVDService
{
第二种初始化映射器的方式,将其分配给一个变量,然后完成初始化,因此该变量将超出范围并立即被垃圾收集,即使在该示例中,我也怀疑他对其进行了测试,因为初始化没有调用适当的方法将映射器存储在任何地方。
在9.0之前,您将需要初始化
Mapper.Initialize(cfg =>
cfg.CreateMap<ClassA, ClassB>()
);
Mapper.AssertConfigurationIsValid();
这将在运行时存储映射器的静态副本,该副本可以在系统中的任何位置进行静态访问,通常,您将在启动时在服务定义中调用此副本,因为它只需要运行一次。这样,您根本不需要在服务定义中调用它。它在整个应用程序中都可用。而你只是这样称呼它
var result = Mapper.Map<ClassB>(classA);
9.0之后,他们删除了静态API,您需要使用依赖项注入,或者你可以看看我的回答How to use AutoMapper 9.0.0 in Asp.Net Web Api 2 without dependency injection?以了解如何解决。