Chain of Responsibility Using Castle Windsor and a First Experience With StructureMap - Part 2
November 16, 2008In my previous post, I outlined an issue that I had with Castle Windsor for configuring multiple chains of responsibility. I want to have different ProcessConsumer classes that require a slightly different chain of processors:
ProcessConsumer1 -> Processor1 -> Processor2
ProcessConsumer2 -> Processor3 -> Processor1 -> Processor2
Solution with Castle Windsor
For achieving this scenario using Castle Windsor, without it throwing a CircularDependencyException at me, I needed to split up the IProcessor interface and the BaseProcessor class like so:
public interface IProcessor
{
void Process(Request request);
}
public interface IChainableProcessor : IProcessor
{
IProcessor Successor
{ get; set; }
}
public abstract class BaseProcessor : IProcessor
{
public virtual void Process(Request request)
{
// Some base class behaviour
FurtherProcess(request);
}
protected abstract void FurtherProcess(Request request);
}
public abstract class BaseChainableProcessor : BaseProcessor,
IChainableProcessor
{
public IProcessor Successor { get; set; }
public override void Process(Request request)
{
base.Process(request);
if(null != Successor)
{
Successor.Process(request);
}
}
}
Chainable processors can now derive from the BaseChainableProcessor class and those processors that should come last in the chain can continue to derive from the BaseProcessor class.
This approach no longer results in circular dependencies. Although it works, I don't like this solution that much because now I can no longer change the order of responsibilities by simply altering the IoC container configuration. If I want to achieve that, I possibly have to change some code as well. This also means that some processors must always come last in the chain, which is not always feasible in complex scenarios.
Solution using StructureMap
One of the things I want to explore in the next couple of months is StructureMap. I was wondering whether this particular IoC container can solve this issue without having to split up the IProcessor interface and BaseProcessor class. It appears that StructureMap can indeed handle this scenario in a graceful way. I just needed to rip out Castle Windsor and replace it with the StructureMap goo. Below you can see the DependencyContainer class that I've been using for this example:
public class DependencyContainer
{
public void Configure()
{
ObjectFactory.Initialize(x =>
{
x.AddRegistry(new CORRegistry());
});
}
public T Resolve<T>()
{
return ObjectFactory.GetInstance<T>();
}
}
Really straightforward stuff. I derived a class from StructureMap's Registry class and added it to the ObjectFactory. Here is the code for my derived registry class:
public class CORRegistry : Registry
{
protected override void configure()
{
ForRequestedType<IProcessor>()
.TheDefault.Is.OfConcreteType<Processor1>()
.WithName("Processor1")
.SetterDependency<IProcessor>()
.Is(y => y.OfConcreteType<Processor2><());
ForConcreteType<ProcessorConsumer2>()
.Configure
.CtorDependency<IProcessor>()
.Is(x => x.OfConcreteType<Processor3>()
.SetterDependency<IProcessor>()
.Is(y => y.TheInstanceNamed("Processor1")));
}
}
That's all I had to do. Everything just works now. I really like the way StructureMap handles things (registry classes) and its configuration is quite easy. This code could probably be improved as these are my first baby steps as a noob. This first pleasant experience certainly motivates me to do some more goofing around with StructureMap.
As always, I'm open for suggestions.
Till next time,
Jan, the injected
If you and your team want to learn more about how to write maintainable unit tests and get the most out of TDD practices, make sure to have look at our trainings and workshops or check out the books section. Feel free to reach out at info. @ principal-it .be
Jan Van Ryswyck
Thank you for visiting my blog. I’m a professional software developer since Y2K. A blogger since Y2K+5. Provider of training and coaching in XP practices. Curator of the Awesome Talks list. Past organizer of the European Virtual ALT.NET meetings. Thinking and learning about all kinds of technologies since forever.
Comments
Writing Maintainable
Unit Tests
Watch The Videos
Latest articles
-
Contract Tests - Parameterised Test Cases
June 28, 2023
-
Contract Tests - Abstract Test Cases
April 12, 2023
-
Contract Tests
February 1, 2023
-
The Testing Quadrant
June 15, 2022
-
Tales Of TDD: The Big Refactoring
February 2, 2022
Tags
- .NET
- ALT.NET
- ASP.NET
- Agile
- Announcement
- Architecture
- Behavior-Driven Development
- C++
- CQRS
- Clojure
- CoffeeScript
- Community
- Concurrent Programming
- Conferences
- Continuous Integration
- Core Skills
- CouchDB
- Database
- Design Patterns
- Domain-Driven Design
- Event Sourcing
- F#
- Fluent Interfaces
- Functional Programming
- Hacking
- Humor
- Java
- JavaScript
- Linux
- Microsoft
- NHibernate
- NoSQL
- Node.js
- Object-Relational Mapping
- Open Source
- Reading
- Ruby
- Software Design
- SourceControl
- Test-Driven Development
- Testing
- Tools
- Visual Studio
- Web
- Windows
Disclaimer
The opinions expressed on this blog are my own personal opinions. These do NOT represent anyone else’s view on the world in any way whatsoever.
About
Thank you for visiting my website. I’m a professional software developer since Y2K. A blogger since Y2K+5. Author of Writing Maintainable Unit Tests. Provider of training and coaching in XP practices. Curator of the Awesome Talks list. Thinking and learning about all kinds of technologies since forever.
Latest articles
Contract Tests - Parameterised Test Cases
Contract Tests - Abstract Test Cases
Contract Tests
The Testing Quadrant
Contact information
(+32) 496 38 00 82
info @ principal-it .be