La pieza MEF no puede importar la fábrica autogenerada de Autofac
Pregunta
Este es un problema (para mí) bastante extraño, porque ya estaba funcionando perfectamente pero falló por completo después de algunos cambios no relacionados.
tengo un Repository
que importa en su constructor una lista de IExtensions
a través de la integración de Autofacs MEF.Una de estas extensiones contiene una referencia a la Repository
como Lazy(Of IRepository)
(perezoso por la referencia circular que se produciría).
Pero tan pronto como intento usar el repositorio, Autofac lanza un ComponentNotRegisteredException
con el mensaje "El servicio solicitado 'ContractName=Assembly.IRepository()' no ha sido registrado".
Sin embargo, eso no es realmente correcto, porque cuando salgo justo después de la compilación del contenedor y exploro la lista de servicios, está allí: Exportado() y con el Nombre de contrato correcto.
Agradecería cualquier ayuda con esto...
Miguel
[Editar] Aquí hay una versión simplificada del código:
Repositorio
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
Enchufar
<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
Iniciador
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
Solución
Ah inmediatamente después de que publicó ese último comentario Creo lo he descubierto:
The requested service 'ContractName=ConsoleApplication7.IDocumentRepository()'
has not been registered.
Tenga en cuenta que hay un par de paréntesis después del nombre de contrato - esto es debido a que el contrato es una función, es decir, este mensaje fue producido por el siguiente constructor, que es ligeramente diferente de la de su muestra:
Public Sub New(ByVal repositoryFactory As Func(Of IDocumentRepository))
_repositoryFactory = repositoryFactory
End Sub
Tenga en cuenta el 'Func' en ese país. MEF, a diferencia de Autofac, no considera Func como un tipo especial y por lo tanto no va a traducir esto en el mismo contrato como para perezoso.
Si desea proporcionar un Func para un componente MEF, es necesario exportarlo como una funcionalidad desde la Autofac. Esto es un poco complicado:
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))
Puede que tenga que jugar con la sintaxis un poco, mi VB.NET es bastante inestable.
Mi conjetura es que hay binarios rancio en su directorio / extensiones que están interfiriendo con la depuración de esto.
Espero que esto está en la marca!
Nick