【问题标题】:Unable to bootstrap a service with ServiceBehavior (AutoMapper "Mapper not initialized")无法使用 ServiceBehavior 引导服务(AutoMapper“映射器未初始化”)
【发布时间】:2019-09-26 13:10:47
【问题描述】:

我遇到了几个问题,但无法正确解决。

在尝试使用 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 构造函数是否运行?

标签: wcf automapper


【解决方案1】:

首先,您需要确保将注释添加到您的服务中以首先调用该行为

[AutomapServiceBehavior]  <-------
[ServiceErrorBehavior(typeof(ElmahErrorHandler))]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class DVDService : IDVDService
{

其次,您初始化映射器的方式是将其分配给 var,然后您的初始化完成,因此 var 将超出范围并立即被垃圾收集,即使在该文章中的示例中,我也怀疑他是否对其进行了测试,因为他的初始化没有调用正确的方法来将映射器存储在任何地方。

在 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? 看看如何解决这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-19
    • 1970-01-01
    • 1970-01-01
    • 2017-06-06
    相关资源
    最近更新 更多