2

这是一个(对我来说)非常奇怪的问题,因为它已经运行得很完美,但在一些不相关的更改之后完全向南运行。

我有一个Repositorywhich 在其构造函数中导入了IExtensions通过 Autofacs MEF 集成的列表。这些扩展之一包含对Repositoryas的反向引用Lazy(Of IRepository)(由于会发生循环引用而变得懒惰)。

但是,一旦我尝试使用存储库,Autofac 就会抛出一条ComponentNotRegisteredException消息“请求的服务'ContractName=Assembly.IRepository()' 尚未注册。”

然而,这并不完全正确,因为当我在容器构建后立即中断并探索服务列表时,它就在那里 - Exported() 并具有正确的 ContractName。

我会很感激这方面的任何帮助......
迈克尔

[编辑] 这是代码的精简版本:

存储库

公共类文档库
    实现 IDocumentRepository

    Private _extensions As IEnumerable(Of IRepositoryExtension)
    
    Public Sub New(ByVal 扩展为 IEnumerable(Of IRepositoryExtension))
        _extensions = 扩展
    结束子

    Public Sub AddDocument(ByVal document As Contracts.IDocument) 实现 Contracts.IDocumentRepository.AddDocument
        对于 _extensions 中的每个扩展
            extension.OnAdded(document.Id)
        下一个
    结束子
结束类

插入

<导出(GetType(IRepositoryExtension))>
<PartCreationPolicy(ComponentModel.Composition.CreationPolicy.Shared)>
公共类 PdfGenerator
    实现 IRepositoryExtension

    Private _repositoryFactory As Lazy(Of IDocumentRepository)
    
    Public Sub New(ByVal repositoryFactory As Lazy(Of IDocumentRepository))
        _repositoryFactory = repositoryFactory
    结束子

    Public Sub CreatePdf(ByVal id As Guid) 实现 Contracts.IRepositoryExtension.OnAdded
        暗淡文档 = _repositoryFactory.Value.GetDocumentById(id)
    结束子
结束类

引导程序

公共类编辑器应用
    继承 System.Web.HttpApplication

    Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        将构建器作为新的 ContainerBuilder()
        
        Dim catalog1 作为新的 TypeCatalog(GetType(DataRepositoryScheme))
        将 catalog2 作为新 DirectoryCatalog(HttpContext.Current.Server.MapPath("/Plugins"))
        builder.RegisterComposablePartCatalog(新 AggregateCatalog(catalog1,catalog2))
        
        builder.RegisterType(Of DocumentRepository).As(Of IDocumentRepository).SingleInstance().Exported(Function(x) x.As(Of IDocumentRepository)())
        
        AutofacServiceHostFactory.Container = builder.Build()
    结束子
结束类
4

1 回答 1

1

啊,在我发布最后一条评论后,我想我明白了:

The requested service 'ContractName=ConsoleApplication7.IDocumentRepository()'
has not been registered.

请注意,合约名称后面有一对括号 - 这是因为合约是一个函数,即此消息由以下构造函数生成,与示例中的构造函数略有不同:

Public Sub New(ByVal repositoryFactory As Func(Of IDocumentRepository))
    _repositoryFactory = repositoryFactory
End Sub

请注意那里的“功能”。与 Autofac 不同,MEF 不将 Func 视为特殊类型,因此不会将其转换为与 Lazy 相同的合同。

如果要为 MEF 组件提供 Func,则需要将其作为 Func 从 Autofac 导出。这有点棘手:

builder.RegisterType(Of DocumentRepository).As(Of IDocumentRepository)

builder.Register(Function(c) c.Resolve(Of Func(Of IDocumentRepository))) _
    .As(New UniqueService()) _
    .Exported(Function(x) x.As(Of Func(Of IDocumentRepository))

您可能需要稍微使用一下语法,我的 VB.NET 相当不稳定。

我的猜测是 /Extensions 目录中有陈旧的二进制文件会干扰调试。

希望这是在标记上!

缺口

于 2010-06-12T21:46:16.457 回答