Dec 10, 2009 at 6:33 PM

I have a WCF service which uses MEF to do its job. I thought this was set up correctly, but am having problem when I call the service twice in immediate succession. This code is tentative, and exceedingly ugly, but it will give you an idea of what I am doing. The MEF composition tends to fail on teh second call (I think). I can try to get more info if this is correct, but I suspect it is not. The initial container is populated with catalogs that it should be safe to share across threads. The child persistence manages having a separate data context for each call. Suggestions please!


   Public Function RetrieveManyUser() As IEnumerable(Of User) Implements IUserWcfServiceSync.RetrieveManyUser
         Dim fullDir = IO.Path.GetFullPath(".")
         Dim ret = InitializeUserServices.RetrieveMany(Nothing).Cast(Of User)()
         Return ret
      Catch ex As System.Exception
         Throw ex
      End Try
   End Function
   Private Function InitializeUserServices(ByVal ParamArray parts() As Object) As IBizServiceSync(Of IUser, Guid)
      ' The modelAssembly is currently being loaded, so we just grab it
      ' HACK: For some reason its starting in a VS directory
      Dim directory = Me.GetType.Assembly.CodeBase.Replace("file:///", "")
      directory = IO.Path.GetDirectoryName(IO.Path.GetDirectoryName(directory))
      directory = IO.Path.Combine(directory, "ServerBin\Persistence")
      MefManager.Manager.ComposeChild(GetType(User).Assembly, directory, Me)
      Return _services
   End Function

Dec 10, 2009 at 7:58 PM

Oops. Forgot the rest of the code...


   Public Function ComposeChild( _
               ByVal assembly As Reflection.Assembly, _
               ByVal directory As String, _
               ByVal ParamArray parts() As Object) _
               As Boolean
      Dim aggregateCatalog As AggregateCatalog = Nothing
      If directory Is Nothing And assembly Is Nothing Then
         aggregateCatalog = New AggregateCatalog()
         ' We assume that if the directory is passed, the corresponding assembly is correct
         _catalogDictionary.TryGetValue(directory, aggregateCatalog)
         If aggregateCatalog Is Nothing Then
            aggregateCatalog = New AggregateCatalog()
            Dim directoryCatalog = New DirectoryCatalog(directory)
            If assembly IsNot Nothing Then
               aggregateCatalog.Catalogs.Add(New AssemblyCatalog(assembly))
            End If
            _catalogDictionary.Add(directory, aggregateCatalog)
         End If
      End If
      'Return ComposeChild(New ComposablePartCatalog() {}, New Object() {})
      Return ComposeChild(New ComposablePartCatalog() {aggregateCatalog}, parts)
   End Function

   Private Function ComposeChild( _
           ByVal catalogs() As Primitives.ComposablePartCatalog, _
           ByVal parts() As Object) _
           As Boolean
      Dim aggregate As AggregateCatalog
      Dim container As CompositionContainer
         aggregate = New AggregateCatalog(catalogs)
         container = New CompositionContainer(aggregate, True, _container)
         Dim batch = New CompositionBatch()
         For Each part In parts
         '      Me._container.Compose(batch)
      Catch ex As Exception
      End Try
      Return True
   End Function