Hi,
I built a website with similar requirements, and it is not hard to do that
with Tapestry. A simple approach is to built a service that returns correct
'Site' instance, and use it everywhere where you need to 'site'.

So instead having
  private Site site;

you would have, e.g.
   @Inject
   private SiteLookup lookup;


and instead using 'site', you would use 'lookup.getSite()'. SiteLookup can
depend on 'Request' service, so there is no need to pass it as argument to
getSite() method.

But, if you are not afraid of some more advanced machinery, you can
contribute your own InjectionProvider, and inject 'Site' directly, something
like:


public class SiteInjectionProvider implements InjectionProvider {
    private final Request request;

    public  SiteInjectionProvider (Request request) {
        this.request = request;
    }

    @Override
    public boolean provideInjection(String fieldName,
@SuppressWarnings("rawtypes") Class fieldType,
            ObjectLocator locator, ClassTransformation transformation,
MutableComponentModel componentModel) {

        if (!Site.class.equals(fieldType)) {
            return false;
        }

        TransformField field = transformation.getField(fieldName);

        ComponentValueProvider<FieldValueConduit> provider =
createProvider(fieldName);

        field.replaceAccess(provider);

        return true;
    }

    private ComponentValueProvider<FieldValueConduit> createProvider(final
String fieldName) {

        return new ComponentValueProvider<FieldValueConduit>() {

            public FieldValueConduit get(final ComponentResources resources)
{

                return new ReadOnlyFieldValueConduit(resources, fieldName) {
                    public Object get() {
                        return ....; // <--- here implement selecting
correct Site based on Request
                    }
                };
            }

        };
    }

}


Remember to contribute your injection provider in your AppModule

    @Contribute(InjectionProvider.class)
    public static void
setupInjectingSite(OrderedConfiguration<InjectionProvider> configuration) {
        configuration.addInstance("site", SiteInjectionProvider .class,
"after:Default");

    }


After that, you would be able to use
   @Inject
    private Site site;

on your pages and components.

Best regards,
Cezary







On Wed, Sep 28, 2011 at 2:39 PM, Sonny Gill <sonny.pub...@gmail.com> wrote:

> Thanks Barry.
>
> Site is a domain layer object and knows nothing about Request/Response etc.
> There will be a limited number of Site objects, one for each site
> supported,
> created and configured at the application start up.
>
> I could set it up as a Service for Tapestry application.
> But can I then provide a Service lookup method that can look at the current
> request, get the correct Site using some criteria, and hand it over to
> Tapestry to inject into the page for current request?
>
> So, something like :-
>
> public Service lookupSiteService(Request request) {
>   String id = ...get site id from the request in some way...;
>
>   SiteRepository repository = ...; // Can I inject an implementation of
> SiteRepository (also a domain layer object) here?
>
>   return repository.getSite(id);
> }
>
>

Reply via email to