Posts in the 'NDecision' category
The posts below all relate to the topic you selected.
If you've not gotten up to speed with the core functionality provided via NDecision it might be good to take a look at the release announcement, which you can find here.
If you're into Aspect-Oriented Programming or you like things to be a little more dynamic and automatic, a second option exists that you might find interesting. The NDecision.Aspects package makes use of the amazing AOP product PostSharp, by SharpCrafters, to enable logic execution automatically at run-time. Rather than write your logical specifications inline, you implement the IHasSpec interface. This interface's single method, GetSpec(), allows you the freedom of wiring up your logic in one place (or in many places, if you prefer to have your specifications split into individual classes based on your own need or preferences).Refactoring the Example for NDecision.Aspects
I'll build on the previous example and refactor the code to use the NDecision.Aspects package and to provide some insight into the difference. First of all, the logic from the original code has been moved into an implementation of the IHasSpec interface.
Once your IHasSpec implementation has been written, the majority of the work is complete. To use the specifications outlined in the IHasSpec implementation, the ApplySpecsBeforeExecution (or ApplySpecsAfterExecution) attribute class can be used to decorate the methods whenever the specifications need to be applied. The screen shot below demonstrates how, using the ApplySpecsBeforeExecution attribute, the rules will automatically be applied prior to the method's logic being executed.
If a second parameter for which there existed IHasSpec implementations were placed on this method, specifications for that parameter would be picked up too. In this way, AOP takes over - for any parameter added to this method for which there exists an IHasSpec implementation, the specifications will be dynamically found and executed on the parameter instance at run-time.
Your rules, in a sense, are automatically applied whenever you want them to be applied.NDecision with AOP, Option Two - Self-Awareness
Now, there may exist a circumstance where your object instances - in this case our favorite childhood cartoon character - should be allowed to do their own work based on the specifications and how they should be applied. In these cases it would be more optimal to have the capability of applying the ApplySpecsBeforeExecution or ApplySpecsAfterExecution attributes to the target class itself (or specifically, to methods of the target class). The code from above has been refactored with this idea in mind. Specifically, we've given Bugs his own method, also decorated with the ApplySpecsBeforeExecution attribute.
Likewise, the program code will need to be changed so that it allows Bugs his autonomy.
Both methods result with the following obvious output - a console window showing the directions Bugs takes on his journey, in the order they were taken.
Just like the NDecision core project, NDecision.Aspects is available for free via NuGet . Don't worry about the dependencies or having to install both packages; simply installing NDecision.Aspects will bring down everything you need, including the PostSharp assembly, as SharpCrafters so generously offer it up as a NuGet package too.
Happy coding! I hope you give NDecision a spin. If you do take the time to play with it, please let me know how it works out for you via the comments form. Or, you can find me on Twitter at @bradygaster.
A pet project of mine for a few months, NDecision is finally going to be allowed to see the light of day. You can get it as a NuGet package right now.
If you'd like to see a video of NDecision being installed and used in a brand new project, there's a video below. Finally, click the NDecision link in the navigation bar above if you'd like to read more about NDecision. There's not a lot to it, but that's kind of the point.
Keep watching this blog and the NDecision page, though, I've got some more stuff related to NDecision I'll be talking about in a few days. For now, grab it and start using the BDD decisioning goodness that NDecision offers!
After the first post on NDecision I realized there’s room for improvement – allow for multiple directions when a test expression passes. This way one .Run() call on a target results in the ability to chain multiple processes together. Kind of like a Saga in ESB, but maybe not quite. Anyway, here’s the test that demonstrates the ability.
This post serves a dual purpose, to add to the list of articles in the series on Generics and Reflection. It also introduces a Fluent business logic processor I’ve built about 100 times in other incantations but I think all eventually leading up to this point. In keeping with my current trend of hypercomplicating the sublime by making giving it a Fluent interface to make it easy for reuse later on, the result was, as my friend Bill Hargett would probably say, is an object-oriented way of representing a procedure. Pretty much. So that’s our goal statement.
Represent the relationship between an object and the steps it takes through a system or the actions on which a process acts out on that object as a series of disconnected objects. Expose the ability to use that decisioning power via a Fluent interface. Use business language-rich unit tests to provide guidance on the manner in which the processes should be executed.
Typical late-night insomnia fodder. Thank goodness for Generics, for they make the whole engine and core architecture of this idea possible in about 200 lines of code. Maybe less.
To get started take a look at the super-simple business entity and exception. You can probably figure out what the business logic looks like. We’ll spell it out in provable statements:
- Allow all users 21 or over to drink
- Disallow all users under 21 to drink
Taking that logic and rolling unit tests is pretty easy.
Given those tests we have a rather common language from which a Fluent interface can be created. Handle a target instance or list of instances using associated method calls. Why method calls and not interfaces? That’d force too much structure. You could have one old app with all the methods you need, just not glued together properly. You refactor a little, tie it all together, and use something like NDecision to direct traffic.
With the unit tests defined and a little imagination and patience applied the Fluent interface takes a structure that makes the business rules quite easy to implement. The test out put is below. you’ll see both tests pass in spite of the fact that the result behavior of the underage run is an exception is thrown; it’s just one the test is actually is expecting.
If you’re interested in this, let me know and I’ll get you a copy of the code. It is pretty short and is probably going to be shown in a future post, so stay tuned.