Issue in DirectoryCatalog

Feb 14, 2009 at 9:32 AM
Hi, 

This is a simple console based application: 

 

[

Export]

 

 

public class Program

 

 

 

 

{

[

Import]

 

 

public IEnumerable<IMessageSender> MessageSenders { get; set; }

 

[

Import("TestMethod")]

 

 

public Action TestMethod { get; set; }

 

[

Import(typeof(ITestInterface))]

 

 

public ITestInterface NonReferredTestMethod { get; set; }

 

 

public static void Main(string[] args)

 

{

 

Program p = new Program();

 

p.Run();

}

 

public void Run()

 

{

Compose();

 

foreach (var _messageSender in MessageSenders)

 

{

_messageSender.Send(

"Message Sent");

 

}

 

TestMethod();

 

NonReferredTestMethod.TestMethod();

 

 

Console.Read();

 

}

 

public void ImportCompleted()

 

{

 

Console.WriteLine("Import Completed!!");

 

}

 

private void Compose()

 

{

 

var catalog = new AggregateCatalog(new[] { (ComposablePartCatalog)new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()) ,

 

 

new DirectoryCatalog(".") });

 

 

var container = new CompositionContainer(catalog);

 

 

 

var batch = new CompositionBatch();

 

 

batch.AddPart(this);

 

 

container.Compose(batch);

 

}

}

This code belongs to a seperate assembly which is not reffered to the executing assembly(above assembly) 

 

[

Export(typeof(IMessageSender))]

 

 

 

 

public

class EmailSender : IMessageSender

 

 

 

 

{

 

public void Send(string message)

 

{

 

Console.WriteLine(message);

 

}

}

 

 

 

public

class MessageSender

 

 

 

 

{

[

Export("TestMethod")]

 

 

public void TestMethod()

 

{

 

Console.WriteLine("testMethod executed.");

 

}

}

 

[

Export(typeof(IMessageSender))]

 

 

 

 

public

class EmailSender1 : IMessageSender

 

 

 

 

{

 

public void Send(string message)

 

{

 

Console.WriteLine(message);

 

}

}

 

[

Export(typeof(ITestInterface))]

 

 

 

 

public

class TestClass : ITestInterface

 

 

 

 

{

 

public void TestMethod()

 

{

 

Console.WriteLine("TestMethod of non-referenced assembly executed!!");

 

}

}

 

 

 

public

interface ITestInterface

 

 

 

 

{

 

void TestMethod();

 

}

 

But when i run the project it gives me following error message:

The composition produced multiple composition errors, with 2 root causes. The root causes are provided below. Review the CompositionException.Errors property for more detailed information.

1) More than one exports were found that match the constraint '(exportDefinition.ContractName = "TestMethod")'.

Resulting in: Cannot set import 'Program.TestMethod (ContractName="TestMethod")' on part 'Program'.
Element: Program.TestMethod (ContractName="TestMethod") --> Program

2) No exports were found that match the constraint '(exportDefinition.ContractName = "ITestInterface")'.

Resulting in: Cannot set import 'Program.NonReferredTestMethod (ContractName="ITestInterface")' on part 'Program'.
Element: Program.NonReferredTestMethod (ContractName="ITestInterface") --> Program

If all the classes are in the same assembly as the executing one then it works fine but the moment i move it to different assembly it doesnt work.
What could be the possible reason for the above exception.

Regards,
Burhan Ghee

Feb 14, 2009 at 5:32 PM
Without trying it myself I would say that the problem is that your DirectoryCatalog is picking up the assembly in the bin folder, resulting in the same exports being identified twice (once by theAAssemblyCatalog and once by the DirectoryCatalog finding the same assembly), this is probably the reason you get multiple matches for 'TestMethod' even though you've only declared one export with that contract.

About the second issue im going to guess its the same problem. The "." path means its not finding the assebly which is exporting something with the 'ITestInterface' contract.. try putting the second assebly in something like "c:\exports\ and change your directorycatalog to DirectoryCatalog(@"c:\exports\") and see if that doesn't solve it