How to organize code for "bigger spaces" ?

Sep 11, 2011 at 6:44 PM

Hi !

My contracts will extend the "PostSet<T0, T1 ...>" limitation in a short future. Additionally, I am
asking me, how to write and configure spaces in the absence of the [remove from API] IOC.

I currently have something like this:

public class TransportCmds :            //Contract
    PortSet
    <
    TransportCmds.ACmd,
    TransportCmds.BCmd,
    TransportCmds.JobCatalogCmd,
    TransportCmds.JobCmd,            //IJob(Cmd)
    JobResult,
    ......................................//8=Limit Xco, 20=Limit PostSet??
    TransportCmds.TopTalkerQuery,
    TransportCmds.IPConnectionInfoQuery,
    TransportCmds.ComputerListQuery
    >
.......

public class ServiceCmds:TransportCmds        //Implementation
{
.......................


When you use the code like this:

    ServiceCmds sc = new ServiceCmds("agent", this.computers);
    TransportCmds tc = space.RunWorker<TransportCmds>(sc, this.c.ServiceName);

you cannot provide a contructed contract, the space will call a parameterless constructor
on it in its own intend.

But I could instatiate a PortSet() and call repeatedly:

AllocatePort<Of <anyType> anyT)

Is this right? Or are there other methods to incject
contracts and implementations??

[The docs on the PortSet.Ports property tell ICollection, but array.
Not clear, if this collection are allowd to call ".Add(..)" on it].

Any help would be great!

Thanks so far and
best regards,

++mabra

Coordinator
Sep 12, 2011 at 7:48 AM
Edited Sep 12, 2011 at 7:50 AM

Hi mabra,

Generally, instead of making Worker with that many message types, I would rather recommend to split the message types up into several workers (depending on which message types are logically related to each other). If your really need to create a worker with a large number of message types, you can use the non-generic PortSet class and hand over the message types to the PortSet constructor. Your contract would then look like this:

class LargeWorkerContract : PortSet
{
	public LargeWorkerContract()
		: base(typeof(MsgType1), typeof(MsgType2), typeof(MsgType3), ...)
	{ }
}


You can then use this contract just like your normally would use one with a generic PortSet. The only difference is that you of course don't have a support for a generic Post method any more. Instead of that your can use the PortSet's PostUnknownType(...) method to post messages.

Hope this helps!

Best regards
Thomas

Sep 15, 2011 at 10:14 PM

Hello Thomas !

Thanks for your answer.

But - for my eyes - the final kick would be, to bring IOC into the game. Your sample requires to have all the types at compile
time. But what about IOC [looks better to me, although, I known some limitations], like this:

class LargeWorkerContract : PortSet
{
        public List<Contract> contracts;

	public LargeWorkerContract()
	{ }
}

I would just inject the types list with setter injection.
Do you think or know, if my snippet "AllocatePort<Of <anyType> anyT)" [from the CCR docs]
could make this working? I would use it in the constructor to start working with that "contracts".

Best regards,

++mabra

Coordinator
Sep 16, 2011 at 8:54 AM

Hi mabra,

Since you are defining a contract, it makes sense in my opinion to also define the message types that the worker can handle (just like you need to define the methods of a WCF service in its contract) - is there a certain reason why you want to inject the message types dynamically? You would also loose the type-safety when posting messages on the client side, which is a big disadvantage I think.

If you really want a worker with completely dynamic message types, I see two possibilities:

  1. You could use constructor injection to hand over the message types (constructor gets a Type[] as parameter)
  2. You could just define your worker to be a Port<object> and then handle the message types yourself internally. For this you could for example create a worker extension that can map received messages to handlers, and use an "AllocatePort" (or "AllocateMessageType") Method to dynamically inject these handlers for certain types.

Best regards
Thomas