I've an entity structure the following:

IManager: IDeletable
{
IEnumerable<IFund> Funds {get;}
IFailureNotification Delete();
}

IFund : IDeletable
{
IEnumerable<IFundClass> FundClasses
IFailureNotification Delete();
}

IFundClass: IDeletable, IInvestable
{
IFailureNotification Delete();
}

And I've got a service that takes an IDeletable and calls Remove onto it. With respect to the return value after that it either commits the transaction or comes it back. I am using NHibernate to persist the classes so can't put RI within the DB and catch the exception (that we wouldn't like anyway).

This can be a classic situation for polymorphism and also the Manager loops through its Funds and removes them before removing itself, the Fund consequently remove the FundClasses before removing themselves, therefore the service can simply take any entity applying IDeletable and realize that the deletion will work the right actions whatsoever levels.

Here's the issue: The fund classes must find if they are getting used inside a completely separate context while using IInvestable interface which they do not know anything about. This involves something - the IInvestmentCalculationService.

Clearly I'd rather not inject the InvestmentCalculationService in to the fund class entity constructor and I'd rather not inject it in to the remove method because this is on Funds and Managers in addition to a number of other classes so does not make sense at all - does mean that the moment we've more needs we must alter the remove techniques on everything.

I am a bit enticed through the Domain Occasions model here: http://www.udidahan.com/2009/06/14/domain-events-salvation/ but I am not certain that it's right as I am looking to get data back in the triggered event handler - which may work but smells a bit wrong, and all sorts of the good examples only show fire and end up forgetting situations.

Does anybody have suggestions?

"Clearly I'd rather not inject the InvestmentCalculationService".

It is the word 'obviously' which i can't stand. I still haven't felt compelled through the is a result of searching "inserting services into organizations". The very best posts about them boil lower to "it does not feel right and you will use domain occasions/double dispatch to get it done anyway so do not do itInch.

Personally, i think it's fine to inject services into organizations and reckon you need to relax a bit about this and get it done. Maybe don't inject the entire InvestmentCalculationService, but inject the BitsOfInvestmentCalculationServiceThatINeedToKnowAboutService if you think the entity does not have to have the whole factor.

Domain occasions isn't any good inside your situation unless of course you give a return value (which essentially causes it to be right into a outfitted up service locator) with double dispatch, the one thing you're inserting needs to originate from somewhere greater in the call stack - most likely an injected value towards the access point class which in most likeliness does not use that dependency.

Just inject the InvestmentCalculationService in to the entity and continue your existence.

One factor we have completed in situations such as these is possess the Remove not perform the actual deletion, but rather make use of a collecting parameter for items to remove. The Remove() method would register itself and then any other objects, which in turn get replayed by another service.

What about getting an interface

public interface ICanBeDeleted<T>
{
    bool CanBeDeleted(T itemToBeDeleted);
}

Before really removing request your container for those implementations of the interface, invoke the CanBeDeleted function and when any return false then don't remove. Your InvestmentCalculationService would implement ICanBeDeleted<FundClass> and register using the container.

Because of all for his or her help, I had been really astounded by the crowd I attracted! I especially loved mcintyre's philosophy and it is truly affected my thinking since. Within this situation though we went for double dispatch. Feels a bit more stable.

Cheers