Autofac错误地解析命名服务

时间:2018-12-13 10:19:27

标签: c# asp.net dependency-injection autofac

我正在使用AutoFac进行依赖项注入,并且global.asax文件中包含以下代码。

builder.RegisterType<GenderMapper>()
    .As<ICodeMapper>().Named<ICodeMapper>(ValueSets.Gender.ToString());

builder.RegisterType<LanguageMapper>()
    .As<ICodeMapper>().Named<ICodeMapper>(ValueSets.Language.ToString());

builder.RegisterType<MaritalStatusMapper>()
    .As<ICodeMapper>().Named<ICodeMapper>(ValueSets.MaritalStatus.ToString());

builder.RegisterType<RelationshipMapper>()
    .As<ICodeMapper>().Named<ICodeMapper>(ValueSets.Relationship.ToString());

builder.Register<Antlr.Runtime.Misc.Func<string, ICodeMapper>>(c =>
{
    var componentContext = c.Resolve<IComponentContext>();
    return (roleName) =>
    {
        var codeMapper = componentContext.ResolveNamed<ICodeMapper>(roleName);
        return codeMapper;
    };
});

ValueSets是一个枚举。我这样解决服务:

var codeMapper = _codeMapperFactory(mapperInstanceName);

_codeMapperFactory实现ICodeMapper的地方,并且是上面注册的4个映射器的基本抽象类。

问题在于,无论mapperInstanceName的值是多少,我总是在最后注册映射器(即RelationshipMapper)。

当我调试时,被调用的构造函数是RelationshipMapper的传递给工厂的参数的值。

这可能是什么原因?

1 个答案:

答案 0 :(得分:2)

在这里有很多需要解压的内容,并且可能需要进行一些来回讨论,因为没有足够的信息,但是我的时间有点短,希望为您提供一个可以帮助您的答案。我可能会或可能不会再回到这里,所以如果我的回答不起作用,最好用其他信息更新您的问题,而不是发表评论并坐下来等我。

所以

我看到您已经将映射器注册为ICodeMapper的未命名命名实现。我还看到RelationshipMapper是最后一个,这意味着如果您解决了一个 unnamed 实现,那将是您将得到的。

// You'd get RelationshipMapper
container.Resolve<ICodeMapper>();

我还看到有一个Antlr.Runtime.Misc.Func<string, ICodeMapper>正在注册。我不知道这种类型是什么,但是我可以看到它很可能与System.Func<string, ICodeMapper>发生冲突。

Autofac处理System.Func,因此,如果调用它,则会得到一个未命名实例。

// You'd get RelationshipMapper
var f = container.Resolve<Func<ICodeMapper>>();
f();

这是我要检查的内容:

  • 确保您可以手动解析已命名的映射器,只是为了确保它可以正常工作。
  • 确保您要解析的是Antlr Func,而不是System.Func
  • 请尝试删除As<ICodeMapper>,仅在不解决任何未命名类型的情况下才使用Named<ICodeMapper>。您可能会开始遇到异常,这可能会帮助您进一步排除故障。就像Autofac抛出未注册任何ICodeMapper的异常一样,您会知道它不是在解决 named 问题,而是在尝试解决 unnamed 问题。
  • 从您的Antlr Func引发异常,而不是调用componentContext.ResolveNamed。看看是否真的受到打击。 (我运气不好,无法在那些从函数生成的函数中设置断点。您也可以在其中尝试一个断点。)

希望有帮助。