The Archer Application Template is my opinionated implementation of a DDD‘ish, CQRS‘ish, Onion Architecture‘ish project template. I use all the ish’es because it isn’t a pure representation of any of them, but borrows concepts from my experience with all of them. I had a few questions asked about it on Twitter and at a recent conference I attended so I thought I would do a blog about it to give more information on what it is and how it can be used.
What is Archer and Why the Name?
I guess I should explain the name. My wife’s nick name is Dutchess. She likes to watch this crazy cartoon named Archer and the main character, Archer, his code name is Dutchess. So, my wife says that her code name is Archer. Well Archer kind of reminds me of architecture so it was only natural to name it Archer…right? And it only made sense to code name the first release Dutchess.
The main reason I created it was so I could have a central location (GitHub) to save the template. I use the folder structure and some of the interfaces and base classes over and over again on projects I work on. I would normally copy and paste it and use it in a new project. Having it in a central location accessible by all the computers I work on was the driver for posting it on GitHub. Actually, I didn’t really think anyone would actually look at it or attempt to use it. You can find it here, but be warned that it is an early work in progress – https://github.com/charleslbryant/ArcherAppTemplate.
In the grand scheme, my vision is provide Core and Infrastructure as a framework of sorts as they provide a pattern that can be reused across projects. I want to compile Core and Infrastructure and reuse the binaries across multiple applications. Maybe even host them on NuGet. This hasn’t been my usage pattern yet as I am still trying to clean them up and stabilize them so I can use them without worrying too much about breaking changes. When will I reach this nirvana? I don’t know because there is no development plan for this.
Right now, one of the primary benefits for me is a reusable folder structure and the interfaces and base classes that I can use to wire up an application’s general and cross cutting concerns with the application infrastructure. I split the architecture into 3 layers: Core, Infrastructure, and Application. The Core project provides interfaces, base classes, and core implementation of various generic application concerns. Infrastructure is a project that provides implementations of various infrastructure related concerns such as configuration, cache, logging and generic data access repositories. Application is an empty project where the specific application concerns are implemented using the Core and Infrastructure.
OK enough fluff, let’s dig a little deeper into the dry documentation.
Cache provides centralized access to the application cache store.
This interface provides the abstraction for application cache and provides for setting, getting, and removing keys from the cache.
This manager allows clients to access cache through the ICache interface by injecting the implementation of cache needed by the client.
Command is the C in CQRS. Commands are basically actions that clients can take in a domain.
This interface is basically a marker to identify a class as a command.
Commands handlers are used to process commands and this interface provides the contract for all command handlers. It exposes an Execute method that is used to kick of command processing. There was a specific question in regards to validation of commands. I validate requests that are passed as commands in the UI. I don’t trust this validation so I also do validation in the command handler, which may include additional validation not included in the UI. Since commands return void, there is no way to return the result of validation through the command. So, when validation fails I will throw a custom ValidationException that includes the reason validation failed. This can be caught higher in the application stack so that messaging can be returned to the user. This may change as I am not yet 100% sure if this is how I want to implement validation. The main take away is there should be multiple points of validation and there needs to be a way to alert users to validation errors, their cause, and possibly how to correct validation issues.
Command dispatchers are used to route commands to the proper command handler. This interface exposes a Dispatch method that is used to trigger the command routing and execution of the command handler’s Execute method.
This provides a default implementation of the ICommandDispatcher interface. It uses Ninject to wire up commands to command handlers.
This interface provides the abstraction for application configuration and provides for setting, getting, and removing keys from the configuration. This is extremely similar to the Cache, but configuration provides a long lived persistence of key/values pairs where cache is just a temporary short lived storage of key/value pairs.
Similar to the CacheManager, this manager allows clients to access configuration through the IConfiguration interface by injecting the implementation of configuration needed by the client.
This is an interesting namespace. Entity is the same as the DDD entity and is basically a way to define the properties of some domain concept. I don’t have the concept of an Aggregate, although I am thinking about adding it as I appreciate the concept in DDD.
This interface just exposes an Id property that all entities should have. Currently it is a string, but I am thinking that it should probably be a custom type because all Id’s won’t be strings, int’s, or Guid’s, but I would like to have to type safety without forcing my opinion on what an Id should be.
This is a basic implementation of IEntity.
This is a basic implementation of IEntity that is based on EntityBase and adds a string Name property. This was added because many of my entities included a name property and I got tired of duplicating Name.
This is one of those areas that need work. I am sure that will have some breaking changes. I am not yet convinced on which implementation of logging I want to base my contracts on.
The current interface for logging exposes one method, Log.
Right now this is a marker class, placeholder. I envision it holding properties that are common to all log entries.
This manager allows clients to access logging through the ILogger interface by injecting the implementation of logging needed by the client.
Messaging in the Archer domain context concerns messaging users through applications like email, IM, Twitter…and more. This is another area that needs to stablize. I have used so many different implementations of messaging and I haven’t settled on a design. Currently, Message is implemented with email in mind, but we may need to abstract it so that messages can be sent to various types of messaging application servers.
This interface exposes one method, Send. The method accepts a Message to send and a MailServer to send it with.
Message is not yet implemented, but it should contain the properties that are used in sending a message.
MailServer is not yet implement, but it should contain the properties that are used to route Message to a MailServer.
This manager allows clients to send mail with the IEmail interface by injecting the implementation of email needed by the client.
Query is the Q in CQRS. Queries are basically requests for data that clients can ask of a domain. Queries look a lot like Commands in the structure of the files that make up the namespace, but the major difference is Commands return void and Queries return a result set.
This interface is basically a marker to identify a class as a query.
Query handlers are used to process queries and this interface provides the contract for all query handlers. It exposes a Retrieve method that is used to kick of query processing.
Query dispatchers are used to route queries to the proper query handler. This interface exposes a Dispatch method that is used to trigger the query routing and execution of the query handler’s Retrieve method.
This provides a default implementation of the IQueryDispatcher interface. It uses Ninject to wire up queries to query handlers.
This is a data access repository that addresses read only concerns, it returns a result set for queries.
This is a data access repository that addresses write only concerns, like commands it does not return a result set, but it does return a bool that signifies if the write action succeeded or not. It violates CQRS in that I am exposing an update and delete method in the interface, but I wanted this to work for non-CQRS implementations, so I assume this is more CQS than CQRS.
I will cover infrastructure, application, and other topics in future posts.