mef - 如何自动进行重组?

发布于 2024-10-02 17:39:14 字数 3229 浏览 0 评论 0原文

我一直在尝试重新组合工作,但没有运气......我尝试了很多次和很多方法 - 没有运气......任何人都可以指出我的错误吗?我希望在我将新的 .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));
    }
}


< br>


AFTER RESPONSE ok, I've added the refresh, but still I don't get why the listbox won't populate with the new data...

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();
    }
}

I've been trying to get recomposition to work but no luck... I tried many times and many approches - with no luck... can anyone point out my mistake? I expect that after I drop a new .dll into plugins directory the Senders collection will be automatically repopulated with new stuff...

//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));
    }
}


AFTER RESPONSE
ok, I've added the refresh, but still I don't get why the listbox won't populate with the new data...

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();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

榕城若虚 2024-10-09 17:39:14

您必须调用刷新你自己。如果您愿意,可以使用 FileSystemWatcher 对象来获取当目录内容发生更改时通知。

You have to call Refresh yourself. If you want you can use a FileSystemWatcher object to get notified when the directory contents have changed.

花海 2024-10-09 17:39:14

它不会重新填充,因为更新字段时,会为该字段设置一个全新的列表。现有集合不会被修改。您必须将其设置为属性而不是字段(您仍然可以将其设置为受保护或私有),然后当调用“set”时,您将更新 listBox1.ItemsSource 和 label1.DataContext。

It won't repopulate because when the field is updated, a brand new List is set to the field. The existing collection is not modified. You have to set it up as a property instead of a field (you can still make it protected or private), then when the "set" is called, you update the listBox1.ItemsSource and the label1.DataContext.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文