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).
精彩评论