Hi Rickard,

Looks very interesting! I haven't had time yet to catch up with the DCI 
discussions, so I'm a little out of the loop. Some quick questions though:

- Are @Structure elements etc. injected with a ServiceImporter in the assembly 
or something like that? 
- If you can't inject vbf, uowf etc into the Context, wouldn't the inner 
classes just be able to access those
- How does your Role class look? That's were self and bind(object) are defined, 
right? Is there a self() method also? (2nd last line)
- I guess it's seldom that you would need different implementations of a Role 
(mixins for an interface, the old way)
- Can you give an example of method name clashing with the old way?

Need to try it out with an example...

Cheers,
Marc

On 2011-08-18, at 08.53, Rickard Öberg wrote:
> The new way: since GroupsContext is basically the only place from which you 
> would do this, and it represents a particular usecase, the "createGroup" 
> method actually belongs in a role in the context, which is only valid *from 
> within that context*. So, the way to do this is to implement GroupsContext as 
> a class and then do the Groups commands thing as an inner class that wraps a 
> Groups object that has Events+Data:
> public class GroupsContext
> {
>   // Injection
>   @Structure
>   Module module;
> 
>   GroupsAdmin groups;
> 
>   public GroupsContext()
>   {
>      groups = new GroupsAdmin(); // Create wrapper
>   }
> 
>   public GroupsContext rebind(Groups groups)
>   {
>      this.groups.bind(groups); // Bind wrapper
>      return this;
>   }
> 
>   public Iterable<Group> index()
>   {
>      return groups.index();
>   }
> 
>   public Group creategroup( StringValue name )
>   {
>      return groups.createGroup( name.string().get() );
>   }
> 
>   class GroupsAdmin
>      extends Role<Groups>
>   {
>      Iterable<Group> index()
>      {
>        return self.groups();
>      }
> 
>      Group createGroup(String name)
>      {
>         Group group = self.createdGroup(null, 
> module.serviceFinder().<IdentityGenerator>findService(IdentityGenerator.class).get().generate(GroupEntity.class));
>         group.changeDescription(name);
>         self().addedGroup(null, group);
>         return group;
>      }
>   }
> }
> ---
> The way to use this in client code would be:
> new GroupsContext().rebind(groups).createGroup(newName);
> 
> The benefits with this solution are:
> * You can create any number of contexts and roles that uses the basic 
> data/event methods, and don't have to worry with method clashing (major issue 
> without this solution).
> * Role code can access members of the Context that wraps it, e.g. "module". 
> If there were more bound objects, those could be accessed directly instead of 
> having them be passed as method arguments to role methods.
> * Easier to see the algorithms as they are directly in the context, rather 
> than having to go one step down into some external mixin.
> * Roles are only visible/usable from within the context that defines them.
> * Very clear what the dependencies of the context are.
> * Invisible from outside that DCI is being used.
> 
> The drawbacks I can see are:
> * Since the roles are wrappers you have to think about what to pass around: 
> wrapper or self() (will almost always be self() since wrapper class is 
> unknown outside of context)
> * Right now cannot use concerns/sideeffects/constraints on inner classes. Can 
> still use on context interaction if implemented as transient though.
> 
> I'm sure there are more benefits and drawbacks, but this is what I can see 
> right now. If anyone has other ideas, that would be great. IF this solution 
> is acceptable, then that changes quite a bit what the typical usage pattern 
> of Qi4j in a DCI setting would be, so it is kind important. It also makes it 
> easier to use DCI outside of Qi4j, since there's nothing really in the above 
> that requires Qi4j, from a pattern point of view.
> 
> WDYT?
> 
> /Rickard
> 
> _______________________________________________
> qi4j-dev mailing list
> [email protected]
> http://lists.ops4j.org/mailman/listinfo/qi4j-dev


_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev

Reply via email to