MEF часть не может импортировать автогенерированный завод Autofac - PullRequest
2 голосов
/ 09 июня 2010

Это (для меня) довольно странная проблема, потому что она уже работала отлично, но пошла на юг после некоторых несвязанных изменений.

У меня есть Repository, который импортирует в своем конструкторе список IExtensions через интеграцию Autofacs MEF. Одно из этих расширений содержит обратную ссылку на Repository как Lazy(Of IRepository) (ленивый из-за циклической ссылки, которая может возникнуть).

Но как только я пытаюсь использовать репозиторий, Autofac выдает ComponentNotRegisteredException с сообщением "Запрошенная служба 'ContractName = Assembly.IRepository ()' не зарегистрирована."

Это, однако, не совсем правильно, потому что, когда я ломаю сразу после построения контейнера и изучаю список сервисов, он там - Exported () и с правильным ContractName.

Буду признателен за любую помощь в этом ...
Michael

[Редактировать] Вот сокращенная версия кода:

Репозиторий

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

Plugin

<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 Ответ

1 голос
/ 13 июня 2010

Ах, сразу после того, как я опубликовал этот последний комментарий, я думаю, что понял это:

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

Обратите внимание, что после имени контракта есть пара скобок - это потому, что контракт является функцией, т.е.это сообщение было сгенерировано следующим конструктором, который немного отличается от того, который вы использовали в вашем примере:

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

Обратите внимание на 'Func' там.MEF, в отличие от Autofac, не рассматривает Func как специальный тип и поэтому не будет переводить его в тот же контракт, что и для Lazy.

Если вы хотите предоставить Func для компонента MEF, вам необходимо экспортировать егов качестве функции от 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 довольно шаткий.

Я предполагаю, что в вашем файле есть устаревшие двоичные файлы/ Каталог расширений, которые мешают отладке этого.

Надеюсь, что это на высоте!

Ник

...