Question

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.

Was it helpful?

Solution

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; }
}

OTHER TIPS

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; } 

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) {
      ...
   }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top