开发者

MEF ComposeExportedValue method

I have the following situation :

I have in UserControl A , in this user control I manage selecting a list of contacts for sending email. I added to its ViewModelA an Action so after filling the contacts I can call this action and this will move the operation with the contacts list to the control which call the UserControlA

 [Import(AllowDefault = true, AllowRecomposition = true)]
 public Action<IEnumerable<Contact>> ActionContactMethod

In UserControl B which contains UserControlA I declared a method void Send(Action<IEnumerable<Contact>> contacts) which is the same signature of the action in UserControl A.

I use MEF composition container to compose it :

CompositionContainer.ComposeExportedValue(new Action<IEnumerable<Contact>>(Send));

This way , when the user choose his contacts then the Action in ViewModelA which wired with the method Send in ViewModelB 开发者_StackOverflowwill happen and the Send method will be called .

The first time I see the recomposition occured and the method send is wired correctly, the second time I'm trying to use the ComposeExportedValue I get an exception, because there is already an Export definition to the Action<IEnumerable<Contact>>.

How I can remove this part from the container so I can compose it again, or if there is another workaround. I used the Compose and the ComposePart method but the recompositions dosn't happen this way.

Thanks in advance...


Using ComposeExportedValue<T> doesn't give you enough control over the ComposablePart instances used during composition. You can control recomposition using CompositionBatch instances. Here is an example class:

[Export]
public class Broker
{
    [Import(AllowRecomposition = true)]
    public Action<string> Writer { get; set; }
}

I've specified a property which is actual a delegate, now look at the following:

class Program
{
    static void Main(string[] args)
    {
        var catalog = new AssemblyCatalog(typeof(Program).Assembly);
        var container = new CompositionContainer(catalog);

        var batch = new CompositionBatch();
        var part1 = batch.AddExportedValue<Action<string>>(ConsoleWrite);
        container.Compose(batch);

        var broker = container.GetExportedValue<Broker>();
        broker.Writer("Hello");

        var batch2 = new CompositionBatch(null, new[] { part1 });
        batch2.AddExportedValue<Action<string>>(ConsoleWrite2);
        container.Compose(batch2);

        broker.Writer("Goodbye");

        Console.ReadKey();
    }

    static void ConsoleWrite(string message)
    {
        Console.WriteLine(message + " from ConsoleWrite");
    }

    static void ConsoleWrite2(string message)
    {
        Console.WriteLine(message + " from ConsoleWrite2");
    }
}

What I've done here, is I've created two separate batches, one which allows me to compose my original delegate, wired up to ConsoleWrite, and one which allows me to remove my original delegate, and then compose my second delegate, ConsoleWrite2. During the first composition, my delegate is wired up in my Broker instance. Now, because I have specified that [Import] to be recomposable, when I compose my second batch, it removes my original part (which is my delegate), and composes my new part (which is my new delegate).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜