mef - как сделать так, чтобы перекомпоновка работала автоматически? - PullRequest
1 голос
/ 15 ноября 2010

Я пытался восстановить работу, но безуспешно ... Я пробовал много раз и много подходов - без удачи ... Кто-нибудь может указать на мою ошибку? Я ожидаю, что после того, как я добавлю новый .dll в каталог плагинов, коллекция Senders будет автоматически заполнена новым материалом ...

//exported classes
[Export(typeof(ISender))]
public class SMTP : ISender
{
    public string Name
    {
        get { return "SMTP plugin"; }
    }

    public void Send(string msg)
    {

    }
}

[Export(typeof(ISender))]
public class Exchange : ISender
{
    public string Name
    {
        get { return "Exchange plugin"; }
    }

    public void Send(string msg)
    {
        // .. blah
    }
}

/ ---------------------------------------------- -----------------------

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    private const string STR_Pugins = ".\\plugins";


    [ImportMany(typeof(ISender), AllowRecomposition = true)]
    private List<ISender> Senders;

    private DirectoryCatalog d;
    CompositionContainer c;

    public MainWindow()
    {
        InitializeComponent();
        listBox1.DisplayMemberPath = "Name";

        ConfigPlugins();
        bindSenders();
    }

    private void ConfigPlugins()
    {
        DirectoryInfo dir = new DirectoryInfo(STR_Pugins);

        if (!dir.Exists)
            dir.Create();

        d = new DirectoryCatalog(STR_Pugins);
        d.Changed += new EventHandler<ComposablePartCatalogChangeEventArgs>(d_Changed);
        c = new CompositionContainer(d);
        c.ExportsChanged += new EventHandler<ExportsChangeEventArgs>(c_ExportsChanged);

        c.ComposeParts(this);
    }

    void d_Changed(object sender, ComposablePartCatalogChangeEventArgs e)
    {
        bindSenders();
        MessageBox.Show("d_Changed " + (Senders == null ? 0 : Senders.Count));
    }

    private void bindSenders()
    {
        listBox1.ItemsSource = Senders;
    }

    void c_ExportsChanged(object sender, ExportsChangeEventArgs e)
    {
        bindSenders();
        MessageBox.Show("c_ExportsChanged "+ (Senders == null ? 0 : Senders.Count));
    }
}




<Ч /> ПОСЛЕ ОТВЕТА хорошо, я добавил обновление, но все еще не понимаю, почему список не заполняется новыми данными ...

public partial class MainWindow : Window
{
    private const string STR_Pugins = ".\\plugins";


    [ImportMany(typeof(ISender), AllowRecomposition = true)]
    private List<ISender> Senders;

    DirectoryCatalog d;
    CompositionContainer c;

    public MainWindow()
    {
        InitializeComponent();
        listBox1.DisplayMemberPath = "Name";

        ConfigPlugins();
        bindSenders();
    }

    private void ConfigPlugins()
    {
        DirectoryInfo dir = new DirectoryInfo(STR_Pugins);

        if (!dir.Exists)
            dir.Create();

        d = new DirectoryCatalog(STR_Pugins);
        c = new CompositionContainer(d);

        c.ComposeParts(this);
    }

    private void bindSenders()
    {
        label1.DataContext = Senders;
        listBox1.ItemsSource = Senders;
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        d.Refresh();
        bindSenders();
    }
}

Ответы [ 2 ]

4 голосов
/ 15 ноября 2010

Вы должны позвонить Обновить самостоятельно. Если вы хотите, вы можете использовать объект FileSystemWatcher , чтобы получать уведомления об изменении содержимого каталога.

1 голос
/ 25 ноября 2010

Заполнение не будет, поскольку при обновлении поля для него устанавливается новый список. Существующая коллекция не изменяется. Вы должны установить его как свойство вместо поля (вы все еще можете сделать его защищенным или закрытым), затем, когда вызывается «set», вы обновляете listBox1.ItemsSource и label1.DataContext.

...