Search code examples
c#wpfmef

MEF Catalog is Empty


I am working a WPF application that uses MEF. But even when I run the below code(As a test code snippet some where in the code), the catalog is always empty. All the sample codes have done the same thing, those are working fine. but mine is not working. I am missing something important that I can not figure out on my own. So,I want some help on this.

var catalog = new AggregateCatalog();        
var x = Assembly.GetExecutingAssembly().Location;

catalog.Catalogs.Add(
new DirectoryCatalog(
          Path.GetDirectoryName(
          Assembly.GetExecutingAssembly().Location)));
CompositionContainer container = new CompositionContainer(catalog);

This is the actual scenario code. there are 3 projects in the same solution.

  1. W PF Project.
  2. Extension Project.
  3. Contract Project.

Extension project contains the Exports. and the contract project contains the interfaces shared by the W PF project and the Extension project.

[Export("LoginManager", typeof(IEmployeeLoginManager))]
public class LoginManager : IEmployeeLoginManager
{
    public EmployeeLoginModel LoginEmployee(String userName, string password) 
    {
        DEmployeeLoginManager employeeLoginManager = new DEmployeeLoginManager();
        return employeeLoginManager.LoginEmployee(userName, password);
    }
}

this Export is used in the WPF project as belows,

public partial class LoginWindow
{
    public EmployeeLoginModel LoggedInEmployee;
    [Import("LoginManager",AllowDefault = true)]
    private IEmployeeLoginManager LoginManager;

    public LoginWindow()
    {
        InitializeComponent();

    }

    private void RadWindow_Closed_1(object sender, Telerik.Windows.Controls.WindowClosedEventArgs e)
    {
        Application.Current.Shutdown();
        Environment.Exit(0);
        return;
    }

    private void RadButton_Click_1(object sender, RoutedEventArgs e)
    {
        string passWord = PasswordText.Password;
        LoggedInEmployee.Password = passWord;

        var container = MEFLoader.GetMEFContainer();
        container.ComposeParts(this);
        EmployeeLoginModel employee= LoginManager.LoginEmployee(LoggedInEmployee.UserName, passWord);

        if (employee.LoginStatus == true) 
        {
            this.Close();
        }

    }

PS: This is the MEFLoader Class:

public static class MEFLoader
{
    public static CompositionContainer GetMEFContainer() 
    {
        var catalog = new AggregateCatalog(new DirectoryCatalog("."), new AssemblyCatalog(Assembly.GetExecutingAssembly()));
        var container = new CompositionContainer(catalog);
        return container as CompositionContainer;
    }
}

I am new to MEF and I appreciate any improvement point as well in my code.

thanks in advance.


Solution

  • First I thought parts in other projects that are in the same solutions are identified automatically by code snippet shown below.

     var catalog = new AggregateCatalog();         
    catalog.Catalogs.Add(
    new DirectoryCatalog(
              Path.GetDirectoryName(
              Assembly.GetExecutingAssembly().Location)));
    CompositionContainer container = new CompositionContainer(catalog);
    

    but it is not like that, we have to manually place the dll in the executing projects bin/debug(since this is running in the debug mode)

    or what you have to do is, you have to change the project properties=> build events => post built event command line to

    copy $(TargetPath) $(SolutionDir)\[Your running application folder]\bin\Debug
    

    this will automatically copy the necessary dlls to the executing bin.

    OR you can change it in the project properties=> build => output path, you can set the output path to the Debug folder of the executing project.