views:

249

answers:

1

I am new to System.Action<T> and Lambda expression. Here is one case I would like to use.

using System;
using System.ComponentModel.Composition;
public class MyClass {
   public static CompositionContainer Container = new CompositionContainer();

   private void Initialize(Action<CompositonBatch> action) {}

   public MyClass() {
      CompositionBatch batch = null;
      inititialize(x=> {
          // create catalog instances: instance1 and instance2 as example
          // ...
          x.AddPart(instance1);
          x.AddPart(instance2);
          batch = x;
       });
       // at this point, will be batch be none-null value will parts added?

       // the following code is composing batch to the container
       Container.Compose(batch);
   }
}

Basically, the method Initialize(Action<CompositionBatch> action) is used to initialize MEF catalog parts to a CompositionBatch instance, which adds all the import and export parts. After that, the batch is composed to the container to resolve all the DI mappings.

I am not sure if I use System.Action<T> and Lambda expression correctly here. Would x be created by Composition() CTOR on-fly in this example? Should I put anything in the method Initialize()? Or should I create a delegate as Initialize() instead(if so I think I still need to bind it to a method)?

+1  A: 

The problem here is that you never invoke your lambda expression. To do that, you need to change your Initialize() method like this:

private void Initialize(Action<CompositonBatch> action) {action(new Composition());}

Note how now you actually call the method you pass to the function. Also, there's a typo in your constructor (intialize rather than Initialize) and I'm not seeing where instance1 and instance2 are declared.

But I'm not sure you really gain anything here. Also be warned that this will create a closure over the batch variable.

Joel Coehoorn
I edited my codes. I am not sure what do you mean by "closure over the batch var". My understanding is that batch is not null after the call of Initialize() and it does have parts in it. Do you mean that I need to define batch as class level var?
David.Chu.ca
I got error with action(); within Initialize() method. It should be something like "action(new Composition());" instead?
David.Chu.ca
Yes, that should do it. I'll edit my answer.
Joel Coehoorn
I think I see your point on closure. One change could be to move batch to class level member, and change the content of Initialize() method to "{ if (batch == null) { batch = new Composition(); } action(batch); }. In this way, calls can be acted on batch in Lambda function calls. Joel, can you update your answer again with my comments if it is correct as alternative way to achieve the same goal?
David.Chu.ca
@David.Chu.ca that sounds good to me.
Joel Coehoorn