[de] MEF und Constructor Parameter (solved)

Topics: Technical Support
Apr 5, 2013 at 3:48 PM
Hallo,

wir haben Zyan jetzt sehr intensiv bei uns implementiert - langsam wächst unser Projekt und es kommen immer mehr Componenten hinzu.

Bis jetzt haben wir jede einzelne Komponente manuel registriert
HostInstance.RegisterComponent(Of IUserManagement)(Function() New UserManagement(CreateServerConn("Users.UsersEDM")))
NLOGLOGGER.Debug("=>: Benutzer Management")

HostInstance.RegisterComponent(Of IOlbMenuManagement)(Function() New OlbMenuManagement(CreateServerConn("OlbMenu.OlbMenuEDM")))
NLOGLOGGER.Debug("=>: Olb-Menu Management")
Nun möchten wir aber nicht immer bei einer neuen Komponente unseren Server neu kompilieren müssen. Daher habe ich versucht das über deine Beschreibung zu MEF zu erreichen
Dim catalog As New AggregateCatalog(New DirectoryCatalog("."))
Dim container As CompositionContainer = New CompositionContainer(catalog)
HostInstance.RegisterComponents(catalog)
Nur an dieser Stelle kann ich ja keine Parameter für den Construktur angeben. Ist dies dennoch möglich und ich hab das nur noch nicht gesehen?

Vielen Dank für die Antwort
Coordinator
Apr 5, 2013 at 7:15 PM
Hi MyKey0815,

sorry I can't answer in German.

MEF supports constructors with parameters. All you need to do is as follows:
  1. Decorate the constructor with ImportingConstructor attribute.
  2. Make sure all parameters can be imported from MEF container.
For string parameters, I'd recommend to use the following trick.
I believe that "Users.UsersEDM" and "OlbMenu.OlbMenuEDM" are configurable parameters.
You may store all such parameters in a Settings class and share it via the same MEF container.
All parameters (connection strings, etc.) will be exposed as properties of the Settings class.

Here is a working sample:
' Compile using: vbc test.vb /r:Zyan.Communication.dll /r:System.ComponentModel.Composition.dll

Imports System
Imports System.ComponentModel.Composition
Imports System.ComponentModel.Composition.Hosting
Imports Zyan.Communication
Imports Zyan.Communication.Composition

Class Program

  Shared Sub Main

    ' Start the server
    Dim Catalog As New AssemblyCatalog(GetType(Program).Assembly)
    Using Host As New ZyanComponentHost("TestMef", 1234)
      Host.RegisterComponents(Catalog)

      ' Start the client (this part can run on a remote machine)
      Using Connection As New ZyanConnection("tcp://localhost:1234/TestMef")
        Dim UserMgmt As IUserManagement = Connection.CreateProxy(Of IUserManagement)
        UserMgmt.Execute()
  
        Dim OlbMenuMgmt As IOlbMenuManagement = Connection.CreateProxy(Of IOlbMenuManagement)
        OlbMenuMgmt.Execute()
      End Using
    End Using
  End Sub

End Class

Public Interface IUserManagement
  Sub Execute()
End Interface

Public Interface IOlbMenuManagement
  Sub Execute()
End Interface

Public Interface IServerSettings
  ReadOnly Property UserManagementParameter As String
  ReadOnly Property OlbMenuParameter As String
End Interface

' In C# projects such file can be generated by VS from app.settings file
' Not sure about VB though...
<Export(GetType(IServerSettings))>
Class Settings
  Implements IServerSettings

  Public ReadOnly Property UserManagementParameter As String _
    Implements IServerSettings.UserManagementParameter
    Get
      Return "Users.UsersEDM"
    End Get
  End Property

  Public ReadOnly Property OlbMenuParameter As String _
    Implements IServerSettings.OlbMenuParameter
    Get
      Return "OlbMenu.OlbMenuEDM"
    End Get
  End Property
End Class

<ZyanComponent(GetType(IUserManagement))>
Class UserManagement
  Implements IUserManagement

  ' This attribute instructs MEF to use this constructor for imports
  <ImportingConstructor>
  Sub New(Settings As IServerSettings)
    Console.WriteLine("UserManagement created. CreateServerConn({0})", _
      Settings.UserManagementParameter)
  End Sub

  Sub Execute Implements IUserManagement.Execute
    Console.WriteLine("Running IUserManagement.Execute...")
  End Sub
End Class

<ZyanComponent(GetType(IOlbMenuManagement))>
Class OlbMenuManagement
  Implements IOlbMenuManagement

  <ImportingConstructor>
  Sub New(Settings As IServerSettings)
    Console.WriteLine("OlbMenuManagement created. CreateServerConn({0})", _
      Settings.OlbMenuParameter)
  End Sub

  Sub Execute Implements IOlbMenuManagement.Execute
    Console.WriteLine("Running IOlbMenuManagement.Execute...")
  End Sub
End Class
Apr 8, 2013 at 6:36 AM
Hello yalli,

thank you very much for your example. It would very helpfull for me.

I can´t put 1:1 in my project, but I understand the technic behind the solution and implemtet at last weekend.

Thank you
Coordinator
Apr 8, 2013 at 12:04 PM
Great!
Glad to hear that.

Don't hesitate to contact me if you need any further assistance.