Smart Client Software Factory / Composite UI App Block

Posts   
 
    
jaschag
User
Posts: 79
Joined: 19-Apr-2006
# Posted on: 06-Nov-2006 19:24:57   

Anyone used these with LL? Would you recommend the combination?

TIA,

Jascha

MarcoP avatar
MarcoP
User
Posts: 270
Joined: 29-Sep-2004
# Posted on: 07-Nov-2006 02:47:24   

jaschag wrote:

Anyone used these with LL? Would you recommend the combination?

TIA,

Jascha

Yep (although they are un-related). smile

jaschag
User
Posts: 79
Joined: 19-Apr-2006
# Posted on: 07-Nov-2006 10:42:40   

MarcoP wrote:

Yep (although they are un-related). smile

I'm asking as I have been looking into these two (SCSF/CAB) and they seem to be worth investigating further but I thought it would be good to find out if there are any gotcha's waiting down the line when plumbing in LL.

sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 07-Nov-2006 13:42:20   

We have used CAB, and I must say I am very pleased with it. The documentation could be better, but the hands on labs are pretty good starters.

MarcoP avatar
MarcoP
User
Posts: 270
Joined: 29-Sep-2004
# Posted on: 07-Nov-2006 14:01:09   

CAB is great and it's actually the first block MS got right the first time around. smile Even if you do not plan on using the block, you will find many design patterns and best practices by studying the code base.

jaschag
User
Posts: 79
Joined: 19-Apr-2006
# Posted on: 07-Nov-2006 15:38:07   

Yeah it looks good. Did it start out as UIProcess AB?

I'm very new to it and trying to get my head round how LL would fit in - do you serialise your entities (possibly entity graph) into the workitem state property?

sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 07-Nov-2006 16:06:14   

User interface process application block is totally terrible if you ask my opinion. I guess they mention in the docs also that Uipab and cab are not related really.

We are using workitem state to store llblgen objects, nothing special there.

jaschag
User
Posts: 79
Joined: 19-Apr-2006
# Posted on: 07-Nov-2006 17:34:05   

sami wrote:

User interface process application block is totally terrible if you ask my opinion.

I'm pleased you said that as I totally agree - spent one day looking at it and that was enough...

sami wrote:

We are using workitem state to store llblgen objects, nothing special there.

Good to hear - will see how much more I can learn from the hands on labs. Apart from the ms & gotdotnet sites, would you recommend any other sources of information / support (user forums)?

MarcoP avatar
MarcoP
User
Posts: 270
Joined: 29-Sep-2004
# Posted on: 07-Nov-2006 18:59:16   

jaschag wrote:

sami wrote:

User interface process application block is totally terrible if you ask my opinion.

I'm pleased you said that as I totally agree - spent one day looking at it and that was enough...

sami wrote:

We are using workitem state to store llblgen objects, nothing special there.

Good to hear - will see how much more I can learn from the hands on labs. Apart from the ms & gotdotnet sites, would you recommend any other sources of information / support (user forums)?

I would not mind answering any questions you may have in regards to CAB or LLBL. If you have google talk or msn, my handle is mpaul31 AT gmail.com.

jaschag
User
Posts: 79
Joined: 19-Apr-2006
# Posted on: 07-Nov-2006 19:12:18   

MarcoP wrote:

I would not mind answering any questions you may have in regards to CAB or LLBL. If you have google talk or msn, my handle is mpaul31 AT gmail.com.

Thanks Marco - I am still early in the learning phase - not quite at the "worthwhile" question stage yet but I will definitely take you up your very kind offer as soon as.

Jascha

RaFaLe avatar
RaFaLe
User
Posts: 27
Joined: 26-Oct-2006
# Posted on: 09-Nov-2006 10:02:49   

We're using CAB / SCSF to deliver a POS solution for a very large retail group. We're also using GenPro for the whole inheritance data model and persistence.

This involves a combination of custom templates that generate interfaces for all of the obejcts as well as partial classes to implement the interfaces for all the business objects. Having an inteface for each of the objects is simply good OO design practice since the client development should be seperate from your services layers.

It's working really well - we've taken the adapter scenario since lazy loading can become a problem when you're using a seperate physcial data access tier. (Just a "heads-up").

So far, the only problems I've run into are related to architecture and my custom templates. Other than that, using GenPro is probably the best decision you can make.

I've used Genpro now for almost 2 years since version 1.x and it's awesome, regardless of the solution and saves an incredible amount of time.

Hope I've given some valuable input smile

jaschag
User
Posts: 79
Joined: 19-Apr-2006
# Posted on: 09-Nov-2006 11:52:16   

RaFaLe wrote:

It's working really well - we've taken the adapter scenario since lazy loading can become a problem when you're using a seperate physcial data access tier. (Just a "heads-up").

Slightly off topic but what transport do you use between tiers (are you transfering LL entities over the wire or just dto's)?

RaFaLe wrote:

So far, the only problems I've run into are related to architecture and my custom templates. Other than that, using GenPro is probably the best decision you can make.

Good to hear. Other than using adapter, any other advice relating to these problems?

Jascha

RaFaLe avatar
RaFaLe
User
Posts: 27
Joined: 26-Oct-2006
# Posted on: 09-Nov-2006 15:34:03   

jaschag wrote:

RaFaLe wrote:

It's working really well - we've taken the adapter scenario since lazy loading can become a problem when you're using a seperate physcial data access tier. (Just a "heads-up").

Slightly off topic but what transport do you use between tiers (are you transfering LL entities over the wire or just dto's)?

RaFaLe wrote:

So far, the only problems I've run into are related to architecture and my custom templates. Other than that, using GenPro is probably the best decision you can make.

Good to hear. Other than using adapter, any other advice relating to these problems?

Jascha

There's no remoting if that's that you're referring to. I have used LL Entities with remoting (TCP) though and it works a treat!

Currently, we're distinguishing between services and smart client by assembly/class only. However, when referring to the data access layer, only services (one particular CAB Module) has access to the DB. When persisting data and calling data (via a lookup service) they all reference one single module. This also means that there are less places to look for errors.

The dependency injection aspect of the SCSF / CAB provides this capability quite nicely.

I don't know if I've answered your question? Maybe some more context, if not?

MarcoP avatar
MarcoP
User
Posts: 270
Joined: 29-Sep-2004
# Posted on: 09-Nov-2006 17:11:29   

Just out of curisosity, how did you guys go about using your LLBL manager classes with your presenters (were they injected via the DI system). What I did was create for example, an ICustomerService interface that wraps the calls to the manager business components. The only problem I've run into is when dealing with smart clients, multi-threading is used and thus the services need to be thread-safe. Did you guys do something similar to this?

jaschag
User
Posts: 79
Joined: 19-Apr-2006
# Posted on: 09-Nov-2006 18:32:38   

Is multithreading mandatory or optional using scsf?

RaFaLe avatar
RaFaLe
User
Posts: 27
Joined: 26-Oct-2006
# Posted on: 10-Nov-2006 05:41:33   

MarcoP wrote:

Just out of curisosity, how did you guys go about using your LLBL manager classes with your presenters (were they injected via the DI system). What I did was create for example, an ICustomerService interface that wraps the calls to the manager business components. The only problem I've run into is when dealing with smart clients, multi-threading is used and thus the services need to be thread-safe. Did you guys do something similar to this?

Yes we used dependency injection. We haven't experienced any issues with thread safety in this scenario. I have interfaces to every LL Business object (Generated through custom templates). I use these interfaces in the presenters / views. The objects are instantiated through one common service which is an entity factory. So:

ICustomerEntity customer = myBusinessObjectFactory.CreateCustomerEntityInstance();

So what the Factory does is this (consider the code below):


private WorkItem _rootWorkItem;
[InjectionConstructor]
public BusinessObjectFactory([ServiceDependency] WorkItem rootWorkItem)
{
     this._rootWorkItem = rootWorkItem;
}
public ICustomerEntity CreateCustomerEntityInstance()
{
     return _rootWorkItem.Items.AddNew<CustomerEntity>();
}
public ICustomerCollection CreateCustomerCollectionInstance()
{
     return _rootWorkItem.Items.AddNew<CustomerCollection>();
}   

I then have a transaction service (module) that provides the persistence model for the entities via the LL Adapter Model.

Make sense?

MarcoP avatar
MarcoP
User
Posts: 270
Joined: 29-Sep-2004
# Posted on: 10-Nov-2006 14:37:44   

Yep, that makes sense. Could you paste a snippet of your persistence service layer? What I do is I have a ICustomerServiceAgent who performs all caching services for the customer data and decides how to fetch the data (webservices or local). So my factory code looks like this:


if (runLocal)
    return new CustomerServiceAgent(new CustomerLocalService);
else
    return new CustomerServiceAgent(new CustomerRemoteService);

So then all my presenters get injected with the service agent interface.

RaFaLe avatar
RaFaLe
User
Posts: 27
Joined: 26-Oct-2006
# Posted on: 10-Nov-2006 14:54:47   

MarcoP wrote:

Yep, that makes sense. Could you paste a snippet of your persistence service layer? What I do is I have a ICustomerServiceAgent who performs all caching services for the customer data and decides how to fetch the data (webservices or local). So my factory code looks like this:


if (runLocal)
    return new CustomerServiceAgent(new CustomerLocalService);
else
    return new CustomerServiceAgent(new CustomerRemoteService);

So then all my presenters get injected with the service agent interface.

I just use the normal LL Adapter for persistence. Nothing fancy at all.

sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 10-Nov-2006 14:56:53   

Nice to see that you both have samekind of approach as I do. I have also have persistance module which handles communication with server components.

A simple code sample would be like this:


    public class SomeService : ISSomeService
    {

        private ISSomeService Service
        {
            get
            {
                return RemotingHelper.GetObject(typeof(ISSomeService)) as ISSomeService;

            }
        }

        public EntityCollection<SomeObject> GetSomeObjects()
        {           
            EntityCollection<SomeObject> foo =  Service.GetSomeObjects();

            return foo;
        }


As you can see I am using remoting here, so remotinghelper handles creating the proxy, which can be either local or remote. If I recall right, the reason why services here are not static is that CAB does not work with static services, as it wants to create instances of them.

jaschag
User
Posts: 79
Joined: 19-Apr-2006
# Posted on: 10-Nov-2006 16:55:36   

sami wrote:

As you can see I am using remoting here, so remotinghelper handles creating the proxy, which can be either local or remote. If I recall right, the reason why services here are not static is that CAB does not work with static services, as it wants to create instances of them.

What are your reasons for using remoting instead of webservices?

sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 13-Nov-2006 10:43:27   

What are your reasons for using remoting instead of webservices?

There actually is quite a many;

1) can't use inherited types in webmethods 2) can't use interface types in webmethods 3) performance (this is a debated issue, but everyone can make their own tests) 4) llblgen + webservices did not mix too well until version 2.0. I have not tried out with 2.0. but I have read that it should be better now. I did not want to go for DTO pattern either. 5) we are not expecting nor wanting to offer access to server components other than from our own client. For integration purposes, we are offering a separate webservice integration layer. 6) And to be honest, the communication mechanism with the server should be so transparent, that it can be changed easily. Just make sure your architecture makes it possible.

tangent
User
Posts: 41
Joined: 30-Apr-2006
# Posted on: 14-Nov-2006 18:49:05   

I am using similar architecture.. online/offline smart client built around SCSF, CAB and Enterprise Library for caching, logging and exception handling. And of course, LLBLGen pro smile

on the server side there is manager classes which deal directly with llblgen entities and then endpoints which wrap them.. then on client side there are service proxies which interface with the server endpoints and service agents that wrap the proxy and also add caching and etc, these agents are registered as services in cab and injected into my cab modules..

i am using remoting at the moment but have been playing around with WCF.. the scenario of using net.tcp when online and queueing messages using net.msmq when offline is definately interesting..

jaschag
User
Posts: 79
Joined: 19-Apr-2006
# Posted on: 14-Nov-2006 22:12:40   

tangent wrote:

I am using similar architecture.. online/offline smart client built around SCSF, CAB and Enterprise Library for caching, logging and exception handling. And of course, LLBLGen pro smile

on the server side there is manager classes which deal directly with llblgen entities and then endpoints which wrap them.. then on client side there are service proxies which interface with the server endpoints and service agents that wrap the proxy and also add caching and etc, these agents are registered as services in cab and injected into my cab modules..

i am using remoting at the moment but have been playing around with WCF.. the scenario of using net.tcp when online and queueing messages using net.msmq when offline is definately interesting..

That sounds like exactly what I am planningsimple_smile Interesting that you are also using remoting - for similar reasons to those above?

sami
User
Posts: 93
Joined: 28-Oct-2005
# Posted on: 20-Nov-2006 10:45:57   

A word of warning regarding logging block and exception handling blocks. Test them out if they really suit for you or not. I myself found them a bit "over-engineered".

For logging we decided to use log4net and I never looked back, excellent piece of work there.

One very annoying feature about logging block (or was it exception handling, not sure) was that it requires you to put assembly's version number in config file. When you increment your assembly version, you have to update your config file aswell. Don't know if this has changed since I used it.