1
votes

I have this class:

public interface IHandles<DOMAINEVENT> where DOMAINEVENT : IDomainEvent
{
    void Handle(DOMAINEVENT args);
}

[Export(typeof(IHandles<IDomainEvent>))]
public class NewMemberWasRegisteredHandler : IHandles<NewMemberWasRegistered>
{
    public void Handle(NewMemberWasRegistered args)
    {
        //EmailSender.Send
        Console.WriteLine("***New Member Registration Email Sent");
    }
}

which I'm trying to Export into:

public class HandlerContainer { public HandlerContainer() { Handlers = new List>(); }

    [ImportMany()]
    public List<IHandles<IDomainEvent>> Handlers { get; set; }
}

The exception I'm getting is:

1) The export 'Multi_Tenant_MEF_Solution.NewMemberWasRegisteredHandler (ContractName="Multi_Tenant_MEF_Solution.IHandles(Multi_Tenant_MEF_Solution.IDomainEvent)")' is not assignable to type 'Multi_Tenant_MEF_Solution.IHandles`1[[Multi_Tenant_MEF_Solution.IDomainEvent, Multi-Tenant-MEF-Solution, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'.

I'm a MEF newb ( 2 hours in ) so this is baffling to me. All the examples I can find use the the parameterless constructors of Import and Export so I'm unclear on what my typeof() or string contracts should be.

1

1 Answers

2
votes

The problem is NewMemberWasRegisteredHandler can't be converted to IHandles<IDomainEvent>. By using MEF and overriding the contract that is exported, you are getting a runtime error, where without MEF you would have gotten a compile-time error. Here's what it would look like without MEF:

public interface IDomainEvent { }

public class NewMemberWasRegistered : IDomainEvent { }

public interface IHandles<DOMAINEVENT> where DOMAINEVENT : IDomainEvent
{
    void Handle(DOMAINEVENT args);
}

public class NewMemberWasRegisteredHandler : IHandles<NewMemberWasRegistered>
{
    public void Handle(NewMemberWasRegistered args) { }
}

public class HandlerContainer
{
    public List<IHandles<IDomainEvent>> Handlers { get; set; }

    public HandlerContainer()
    {
        Handlers = new List<IHandles<IDomainEvent>>();

        Handlers.Add(new NewMemberWasRegisteredHandler());
    }

}

You get a compilation error that you can't convert NewMemberWasRegisteredHandler to IHandles<IDomainEvent>. This is because DOMAINEVENT is not covariant in the IHandles interface. You can make it covariant by adding the out keyword, but then your Handle method wouldn't be legal.