views:

188

answers:

3

I am in the process of converting some of my code to MEF from a proprietary system that sort of does the same thing as MEF, and I have a question about how I would accomplish the following problem that I recently ran into.

I have a typical entity object that looks something like this:

public class Account {

    [Import]
    public IAccountServerService { get; set; }
}

And a service object that needs to be imported in to the above entity object:

public class AccountServerService : IAccountServerService {

    [ImportingConstructor]
    public AccountServerService (Account account) { ... }
}

To put this into words I need the account parameter passed into the AccountServerService constructor instance to be the object of the calling Account object. So that it act like this:

public class Account {

    public IAccountServerService { get { return new AccountServerService (this); } }
}

Please let me know if this scenario is possible or if I have to refactor my service interface in this instance.

A: 

I'm not sure if mutually recursive contracts are or are not possible in MEF. I would factor it out a bit into the following which doesn't require mutually recursive service contracts.

interface IAccountFactory {
  Account CreateAccount(IAccountServerService service);
}

[Export(typeof(IAccountFactory))]
sealed class AccountFactory {
  Account CreateAccount(IAccountServerService service) {
    return new Account(service);
  }
}

class Account {
   Account(IAccountServerService service) {
      ...
   }
}
JaredPar
I guess I am up a creek with out a paddle then. Because I would love to do it this way, but the use of Entity Framework sort of prevents this from being possible.
Nick Berardi
A: 

So MEF does support circular dependencies but they must both be property imports, neither of them can be constructor imports. So the following should work from a MEF standpoint, of course I'm not sure if this approach is blocked by some other constraint you have.

public class AccountServerService : IAccountServerService {
    [Import]
    public Account Account { get; set; }

    public AccountServerService () { ... }
}

public class Account {
    [Import]
    public IAccountServerService { get; set; }
}
Wes Haggard
+1  A: 

If you can change one of the imports in the circular dependency chain to be a lazy import it should work. For example:

[Import] 
public Lazy<IAccountServerService> { get; set; } 
Daniel Plaisted