views:

75

answers:

2

Lets say i have a traditional statemachine/Factory implemented like

public class StateMachine
{
    public void ProcessState(StateEnum CurrentState)
    {
        switch (CurrentState)
        {
            case StateEnum.New:
                ProcessNewState();
                break;
            case StateEnum.Waiting:
                ProcessWaitingState();
                break;
            ++++ More states.....
        }
    }

    void ProcessWaitingState()
    {
        //Do State work
    }

    void ProcessNewState()
    {
        //Do State work
    }
}

But now i want to implement this using best practices (TDD, SOLID...) and structuremap.

To follow the Single responsibility principle I want to put the processing code for each state in separate classes. Also each class has their own set of unique dependencies and they can be pretty complex them self. So putting them in separate classes a good idea I think.

So, how I can i properly do this in Structuremap?

I know this is basically a Factory class that i want to convert to a Objectfactory.

I am using latest Structuremap version 2.54 and in this version a lot of things seems to be deprecated (or not recommended anymore), like the use of ForRequestedType. So I am looking for the correct way of thing this using the new notation.

A: 

I found what I was looking for

First I register using:

For<IStateWorker>().Add<WorkerState_NewState>().Named("new");
For<IStateWorker>().Add<WorkerState_WaitingState>().Named("waiting");

Then I call it using:

        Worker = ObjectFactory.GetNamedInstance<IStateWorker>("waiting");
        Worker.Execute();
        Worker = ObjectFactory.GetNamedInstance<IStateWorker>("new");
        Worker.Execute();

That works.

But my question remains if there's an better way of doing it?

Andy
A: 

Based on both your question and answer, you could use a string representation of the enum value as your name for the named instance, in the registry:

For<IStateWorker>().Add<WorkerState_NewState>().Named(StateEnum.New.ToString()); 

And in your factory code:

public void ProcessState(StateEnum CurrentState)  
{  
   Worker = ObjectFactory.GetNamedInstance<IStateWorker>(CurrentState.ToString());
   Worker.Execute();
}  

Consider the above to be pseudocode, as I obviously don't have your source code, and I normally use the "ForRequestedType<>().AddInstances()" syntax to register types.

Since your IStateWorkers are now managed by the container, you can add constructor dependencies to each one without having to worry about how they get resolved (outside of registering them, of course).

Phil Sandler