MEF部分无法导入Autofac自动生成的工厂

时间:2010-06-09 16:04:25

标签: mef autofac

这对我来说是一个非常奇怪的问题,因为它已经完美运行但在经过一些无关的改变之后完全向南。

我有一个Repository,它通过Autofacs MEF集成在其构造函数中导入IExtensions列表。其中一个扩展包含Repository作为Lazy(Of IRepository)的反向引用(由于将出现循环引用而延迟)。

但是当我尝试使用存储库时,Autofac会抛出ComponentNotRegisteredException,并显示消息“所请求的服务'ContractName = Assembly.IRepository()'尚未注册。”

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

我很感激你的任何帮助...
迈克尔

[编辑]这是代码的稀疏版本:

存储库

Public Class DocumentRepository
    Implements IDocumentRepository

    Private _extensions As IEnumerable(Of IRepositoryExtension)

    Public Sub New(ByVal extensions As IEnumerable(Of IRepositoryExtension))
        _extensions = extensions
    End Sub

    Public Sub AddDocument(ByVal document As Contracts.IDocument) Implements Contracts.IDocumentRepository.AddDocument
        For Each extension In _extensions
            extension.OnAdded(document.Id)
        Next
    End Sub
End Class

插件

<Export(GetType(IRepositoryExtension))>
<PartCreationPolicy(ComponentModel.Composition.CreationPolicy.Shared)>
Public Class PdfGenerator
    Implements IRepositoryExtension

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

    Public Sub CreatePdf(ByVal id As Guid) Implements Contracts.IRepositoryExtension.OnAdded
        Dim document = _repositoryFactory.Value.GetDocumentById(id)
    End Sub
End Class

引导程序

Public Class EditorApplication
    Inherits System.Web.HttpApplication

    Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        Dim builder As New ContainerBuilder()

        Dim catalog1 As New TypeCatalog(GetType(DataRepositoryScheme))
        Dim catalog2 As New DirectoryCatalog(HttpContext.Current.Server.MapPath("/Plugins"))
        builder.RegisterComposablePartCatalog(New AggregateCatalog(catalog1, catalog2))

        builder.RegisterType(Of DocumentRepository).As(Of IDocumentRepository).SingleInstance().Exported(Function(x) x.As(Of IDocumentRepository)())

        AutofacServiceHostFactory.Container = builder.Build()
    End Sub
End Class

1 个答案:

答案 0 :(得分:1)

在我发布最后一条评论之后我立即想出来了:

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

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

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

注意那里的'Func'。与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目录中有过时的二进制文件干扰了调试。

希望这是标志性的!

尼克