I've created ISIS-493 [1] for this idea; I think it has merit. As Oscar says, there are a bunch of possible follow-ons, eg improved BDD spec support, or automatic registration of services (rather than in isis.properties).
There are also some cases where I think we emperically guess which objects are services (looking for an injectXxx prefix); could remove that as well. Dan [1] https://issues.apache.org/jira/browse/ISIS-493 On 31 July 2013 15:57, GESCONSULTOR - Óscar Bou <[email protected]>wrote: > > Hi, Dan. > > > yup, I like the idea, I think... though I'd probably use @DomainService > > instead of @IsisRepository. > > Well, perhaps we need two. But I consider relevant to be able to > distinguish "Repositories" as defined in DDD from the other kind of Domain > Services. > > The @DomainService annotation would mark a service as that. > > But the @IsisRepository(entity=XXXX), @Repository(entity=XXXX), etc. would > have the additional meaning to be acting as the repository for a specific > kind of Domain Entities, so the "entity=XXXX" param should be mandatory. > > They should also be considered as Domain Services. > > > - is it your intention to generalize the > > "findPartyByReferenceOrName(String)" bit (in the catch block) also? If > so, > > wouldn't that require that DomainService would need to be an interface > > (declaring findById(...)) rather than a simple annotation? > > Yes. In fact, we currently have a generic "findByName", "findByProperty", > etc methods on a generic abstract repository, implemented with the help of > the IsisJdoSupport service. We are "multi-tenant", and that allows us to > always filter by tenant and apply some other business filters. We use those > protected methods on the domain "finders" defined on each entity's > repository. > > As we are sharing the implementation, we chose inheritance, but an > interface would also do the trick. > > But we consider that an "implementation detail" in addition to the > annotation, not a replacement. > > > > - I'm not sure about how hierarchies of classes work. for example, we > have > > Parties domain service, for any sort of Party, but also Organisations > > domain service, for Organisation (subtype of Party) and Persons domain > > service (for Person, subtype of Party). The entities are closely related > > through inheritance, but I don't really have a pattern to explain to > myself > > what the relationship should be (if any) between their corresponding > domain > > services of Parties, Organisations and Persons. > > In our case, we have references to "Parties" on other Domain Entities, so > we need to be able to associate "Parties", in addition to "Organizations" > and "Persons". So we need to have "finders" for Parties. If that's the > case, we need the "Party Repository", in addition to the "Organization > Repository" and the "Person Repository". No need for inheritance between > them, unless you have to share the implementation of some methods, > validations, etc. That was not our case. All them inherit from the > "abstract base domain repository". > > But what we have needed is the ability to distinguish between "creation" > actions or "factory methods" (we firstly implemented it by searching for > methods defined on services and starting with "create", but we changed > after to an annotation called "@FactoryMethod" - perhaps other names are > better, and names are important on DDD, we know :-) ) in order to be able > to know "how" to create a "Party" descendant (on Edit forms and action > params we are offering the user the option to create a new entity in > addition to select from an existing one). > > > > > > > > > El 26/07/2013, a las 12:08, Dan Haywood <[email protected]> > escribió: > > > Hi Oscar, > > yup, I like the idea, I think... though I'd probably use @DomainService > > instead of @IsisRepository. > > > > Another benefit is that we can use it to automatically locate services so > > that they don't need to be explicitly registered - something that you've > > asked for in the past, IIRC. A suitable implementation of > > org.apache.isis.core.runtime.services.ServicesInstaller would do the > trick, > > I think. > > > > It might need a few iterations to get exactly correct, however. A > couple > > of questions I have is: > > - is it your intention to generalize the > > "findPartyByReferenceOrName(String)" bit (in the catch block) also? If > so, > > wouldn't that require that DomainService would need to be an interface > > (declaring findById(...)) rather than a simple annotation? > > - I'm not sure about how hierarchies of classes work. for example, we > have > > Parties domain service, for any sort of Party, but also Organisations > > domain service, for Organisation (subtype of Party) and Persons domain > > service (for Person, subtype of Party). The entities are closely related > > through inheritance, but I don't really have a pattern to explain to > myself > > what the relationship should be (if any) between their corresponding > domain > > services of Parties, Organisations and Persons. > > > > Let's exchange a few more mails on this before going ahead and writing > some > > new code on it.... > > > > Dan > > > > > > > > > > On 24 July 2013 20:16, GESCONSULTOR - Óscar Bou <[email protected] > >wrote: > > > >> > >> Hi, Dan. > >> > >> We are implementing some BDD tests. And we have the need to always write > >> custom spec transformers (one for each domain entity class) like this > one: > >> > >> public class ETO { > >> private ETO() {} > >> ... > >> > >> public static class Party extends > >> NullRecognizingTransformer<org.estatio.dom.party.Party> { > >> @Override > >> public org.estatio.dom.party.Party transformNonNull(String id) { > >> try { > >> return ScenarioExecution.current().getVar("party", id, > >> org.estatio.dom.party.Party.class); > >> } catch(IllegalStateException e) { > >> return > >> > ScenarioExecution.current().service(Parties.class).findPartyByReferenceOrName(id); > >> } > >> } > >> } > >> > >> > >> If we had an annotation like > >> "@IsisRepository(org.estatio.dom.party.Party.class)" for annotating the > >> Party's repository, the previous transformer could be "generalized" > >> (previously searching also for a var on the Scenario context with the > class > >> name in camelCase). > >> > >> Obviously, if none is found it should be mandatory to declare a > >> transformer. > >> > >> There could be also other scenarios where could be useful to be able to > >> know what's the repository for a given domain entity class. Sure you can > >> think about more. > >> > >> The container (or any other Isis class) could have a method for > returning > >> the proper repository for a class. > >> > >> What do you think? Could it be useful? Any problems derived from it? > >> > >> Thanks, > >> > >> Oscar > >> > >> > >> > >> > >> > >> > >> > >> > >
