MEF Teil nicht in der Lage Autofac automatisch generierte Fabrik importieren
Frage
Dies ist ein (für mich) ziemlich komisch Problem, weil es schon perfekt lief aber ging völlig Süden nach einigen nicht verwandten Änderungen.
Ich habe eine Repository
die Einfuhren in seinem Konstruktor eine Liste von IExtensions
über Autofacs MEF Integration bekommt. Eine dieser Erweiterungen enthält eine Rückreferenzierung zum Repository
als Lazy(Of IRepository)
(faul, weil der Kreis Referenz, die auftreten würde).
Aber sobald ich versuche, das Repository zu verwenden, wirft Autofac eine ComponentNotRegisteredException
mit der Meldung „Der angeforderte Dienst‚ContractName = Assembly.IRepository ()‘wurde nicht registriert.“
Das ist aber nicht wirklich richtig, denn wenn ich direkt nach dem Container-Build brechen und die Liste der Dienste erkunden, es ist da -. Exportierte () und mit dem richtigen ContractName
Ich würde schätzen jede Hilfe zu diesem ...
Michael
[Bearbeiten] Hier ist eine Ausdünnungs Version des Codes:
Repository
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
Bootstrapper
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
Lösung
Ah unmittelbar nach habe ich geschrieben, dass die letzte Bemerkung Ich glaube, ich es herausgefunden:
The requested service 'ContractName=ConsoleApplication7.IDocumentRepository()'
has not been registered.
Beachten Sie, dass es ein Paar von Klammern nach dem Vertragsnamen ist - das ist, weil der Vertrag eine Funktion ist, das heißt, wird diese Meldung durch den folgenden Konstruktor erzeugt wurde, die sich von der in der Probe ist etwas anders:
Public Sub New(ByVal repositoryFactory As Func(Of IDocumentRepository))
_repositoryFactory = repositoryFactory
End Sub
Beachten Sie die 'Func' drin. MEF, im Gegensatz zu Autofac, betrachtet nicht Func als eine besondere Art und so wird dies nicht in den gleichen Vertrag übersetzen, wie für Faule.
Wenn Sie eine Func zu einem MEF-Komponente zur Verfügung stellen möchten, müssen Sie es als Func von Autofac exportieren. Das ist ein bisschen schwierig:
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))
Sie müssen möglicherweise mit der Syntax ein wenig spielen, mein VB.NET ziemlich wackelig ist.
Meine Vermutung ist, dass es abgestanden Binärdateien in Ihrem / Extensions-Verzeichnis, das mit dem Debuggen dies stören.
Hope dies ist auf die Marke!
Nick