Posts tagged Architecture
Five Things to Know About the WCF Runtime
Jan 19th
Since working with WCF I have gleaned quite a bit about how the runtime works through reading various blogs and writing proofs-of-concept/experiments. One thing that has become apparent to me is that many people working with WCF do not fully understand how it works because Visual Studio makes it very easy to create & consume WCF services. In most cases there is no need to understand the “guts” of WCF, but you may reach a point where you want to extend WCF. Here are five things that will help you know where to begin your quest for extension.
.Svc file are the activators that kick off the WCF runtime. In IIS or WAS, .Svc files are what activates a service host which in turn creates a service host and calls your service. The .Svc file specifies the full name of your class and an optional service host factory. If you are self-hosting a service you are responsible for implementing the same functionality in code.
ServiceHosts control your service instances and dispatch calls to your service using ChannelDispatchers. The ServiceHost is the central actor and you can control a lot of behavior by altering the service host or extending it. If you want to use an Inversion of Control container with WCF the best place to stick it is on a custom ServiceHost. The service host also maintains listeners that enable your service to receive calls over the wire at the specified endpoint (e.g., http://mydomain.com/services/myservice.svc).
ServiceHostFactory creates a ServiceHost. If you want to create a custom service host you’ll need a ServiceHostFactory to return an instance of your service host to the WCF runtime.
Everything can be done through configuration or code. I used to be a huge configuration fan, but after dealing with WCF configuration in .NET 3.5 it can get hairy, especially when you have dozens of services. Favor code where you can and save configuration for the stuff that could really change. WCF in .NET 4 has far less configuration, especially in development (which is good because the last thing you want to fight is configuration problems during development of your service).
By default service instances are created per call. This is typically OK and helps you avoid most threading problems. Try to avoid creating expensive objects within your services constructor or any of its dependencies as this could delay your services response time. You can change this using the InstanceContextMode on your service class. Tip: If you are using a container to resolve service instances then you need to remove the InstanceContextMode attribute and let the container manage instances.
(Bonus, a 6th thing to know!) WCF has many extension points, the biggest one being behaviors. Behaviors allow you to control how the service executes at runtime. This applies to anything from instancing to message inspection, and much more. Here are a few posts to get you started:
Lessons Learned About Being a Software Architect By Trying to Be One
Jan 14th
For most of my software development career I cared about how software was organized, how I had to work with it; how I had change it. I never had any formal training or courses on being an architect and, until recently, it seemed like such courses were few and far between.
Over the last few years I learned a lot about being a software architect through trials by fire. When I left the Library world and transitioned into the Justice world I had to step up my game quite a bit. During that time I learned what it took to build systems that had to work round-the-clock. I learned what it took to make disparate systems talk to each other to perform work and remain autonomous. I even tried my best to do things the way I was learning. But often times I was learning more than I could apply and at the pace work was coming at me I couldn’t rewrite systems just to apply new things I learned.
The first thing I learned was that you can’t do it alone. I knew that there was a better way to do things and I couldn’t settle for the status quo. I also didn’t agree with all my coworkers, so I went outside for help. Getting outside perspective was huge and hooked me into people who share industry best practices. Blending that knowledge with inside perspective helped me see where best practices fit into the environment.
The next thing I learned is that people probably won’t like you. Something about architects being perceived as telling people how to code leaves architects out of popularity contests. Personality also works against you too. Learning to control the personality traits that work against you (unwillingness to be flexible, “my way, no highway option”) and helping people discover best practices in the way they need to learn will help. Both of those take time to do and you can’t reach those goals all at once. The architects who learned this lesson are some of the best and I am fortunate to know a few of those architects.
You have to be willing to constantly question yourself. Software architects have to make a lot of assumptions. Part of the key to success is to get good at making good assumptions. Another part is to know when to question yourself and when to be OK with something. These two attitudes can work for you and against you. You’ll know when something is as right as its going to be.
Software architecture is personal and you have to be open to exposing how you think to others. This is hard. Especially when someone who you think is not capable of objectively reviewing a solution reviews one and gives you negative feedback. Dealing with that requires more interpersonal skills than anything. Be prepared to make mistakes and see lesson #2.
The final lesson I learned is that you will never be done learning and it takes small leaps to make big ones. I was introduced to OO patterns by a Java programmer. I was clueless. As I studied those patterns and the concepts taught, I struggled to apply them in an OO world. But in the SOA world things started to make sense. Encapsulation. Abstraction. Loose-coupling. Suddenly concepts and patterns made sense at the OO level. For me to learn I had to see the problems in context. My context was SOA and the bigger picture. When it all clicked, that “a-ha” moment helped me make leaps that I never imagined possible.
For a few years now I have considered myself an architect though I have never had that title from an employer. A good friend and mentor told me that the way I worked and what I did made me an architect. He had that title once, so I felt ok taking that advice from him.
The truth is, every developer is a little bit of an architect. Some of us just care a little more than the next guy.
Using Dependency Injection Containers Effectively
Jan 6th
Out of all the SOLID principles the one I feel the strongest about is Dependency Injection (DI). The motivational poster Derick Bailey created sums it up the best. Why are we hard-coding our systems together, making them harder to test, and harder to change?
Containers evolved to support DI at runtime so we could apply inversion of control. Containers also give us some other things we can leverage besides just keeping track of all those dependencies. We have to be careful not to go container crazy though!
Containers can manage object lifetimes. Ever had to write a singleton? With the availability of containers you almost don’t have to anymore. Before you write your next singleton, think about letting a container manage that lifetime for you.
Use containers to enforce interface/abstract dependencies. Refer to the motivational poster referenced above. Do you really want to solder the light to the socket?
Make sure you initialize and maintain the container at the right level. Ideally your application should have one container to serve all. In WCF you want this to be at the Service Host level. In ASP.NET it will be something initialized in global.asax.
Encapsulate your container initialization in a class. I refer to these classes as “Providers”, ex StructureMapProvider or ContainerProvider (Manager might also work too). This class should be responsible for initializing the container and maintaining the reference to it. When you need to change your dependencies there’s one place to make that change.
Use containers to handle abstractions built around third-party dependencies or types you don’t own. Be careful not to follow this anti-pattern pointed out by Jeffrey Palermo.
Favor code based configuration over .config files. Say what? Configuration files are great for a lot of things. By setting up a container in one you may think, “Great, now I can just change the .config to add new types, etc”. Realistically you are probably never going to do that. Why do I say this? Because I used to believe that I would use .config that way. And it never happened.
Currently my favorite container is StructureMap. Your mileage may very and fortunately, there are a lot of choices out there.
The Power of Patterns
Jan 5th
Design Patterns have been around for some time now but many of us are still learning how and when to leverage these powerful concepts for engineering software. Design Patterns have also been the source of backlash for those who have suffered under design pattern crazed architects. As with any useful tool or concept the balance lies somewhere in the middle.
Patterns exist even when you don’t see them. If I had to choose a way to describe my early programming career (classic ASP & MS Access/MySql) it would be “DRY” (don’t repeat yourself). I spent a lot of time doing things to avoid duplicate work. In ASP this meant lots of include files and shared routines. This led to some common patterns that I used to tackle certain problems; by no means were these actual design patterns, it was just a way I found to best solve the problems I encountered. Looking back on that early experience I see how the design patterns could have helped.
When framing the problem if you see a pattern try to leverage it to solve the problem. Before the holidays the project architect (We’ll call him “Brad”) and I were trying to tackle a problem. As he was looking at what we were doing he suggested the strategy pattern. We weren’t sure it was a good fit but it gave us something to look at to help us with the problem.
One of the barriers to understanding patterns is a lack of real-world examples. If you study the strategy pattern I referred to above you’ll see most of the examples discuss simple calculations, A+B type of stuff. That is helpful, but what if I have 4 factors that are needed to calculate the price and there is other data we must include with the price, like if there was a discount, etc? Does that mean I can’t use the strategy pattern?
Patterns require you to generalize and forget about your specific domain. This is probably the hardest part. A lot of people think that their situation is totally unique; for the domain it may be, but in reality a lot of people have the same problems. This is where patterns really help.
One of my goals for 2010 will be to continue studying and applying patterns where they fit. Some great resources I’m using are:
What Do You Call It? Naming WCF Operations & Messages
Dec 30th
WCF is a great addition to the .NET framework. Like all parts of the framework it introduces a lot of new concepts to learn. Sometimes it’s hard to separate those technical concepts from the decisions like, “What is the best way to architect this service” or “How should I name things?”
Simon Segal, a fellow .NET and SOA junkie posted back in November about how he names operations and messages within WCF and the nServiceBus framework (an open-source Enterprise Service Bus). Simon, like I do, follows a convention of naming in relation to the business events the operations and messages represent.
When it comes to naming operations we not only imply some intent of the operation we also imply what data might be needed. When designing services that are more coarsely grained you often run into issues with what data is really required for the service to perform its work. Simon linked to an article from Thomas Erl, a respected authority on SOA, in which Thomas made the following statement (my emphasis):
Although it is practical and extensible, the use of optional parameters should be limited within Web services. Optional parameters can lead to convoluted service interface designs and a myriad of confusing data exchange scenarios. Additionally, the extent to which optional values can be accommodated is often limited by the underlying XML schemas that define the message structures. Standardized schemas that represent established corporate documents may impose rigid data structures.
Coming from the NIEM world I often emphasized that data exchanges only need 80% of what we think is needed. There were times when people would want to exchange flags or indicators that could be derived from other fields or were not necessarily needed at all. Any time we strayed away from the 80% the services became more difficult to consume and maintain.
Let’s Look at An Example
Factoring all of this in, let’s consider an example of how we might name service operations and messages.
Definitions:
Service Operation – A method you call on a service.
Message – An input/output of a call to a service operation.
Message Parts – Data elements that are included in the message.
Problem: You need to name messages and service operations for a service that will allow customers to place orders for widgets. This service should also allow orders to be cancelled. Orders consist of a unique ID, a customer Id, and widgets.
Request/Response example:
- Service Operation PlaceWidgetOrder, Message: PlaceWidgetOrderRequest, Message Parts: WidgetOrder (Id, Customer Id, Widgets[] (or WidgetCollection))
- Service Operation CancelWidgetOrder, Message: CancelWidgetOrderRequest, Message Parts: OrderId
Event-Driven example:
- Service Operation: CustomerPlacedWidgetOrder, Message: CustomerPlacedWidgetOrderMessage, Message Parts: same as request/response example
- Service Operation: CustomerCancelledWidgetOrder, Message: CustomerCancelledWidgetOrderMessage, Message Parts: same as request/response example
Notice the difference between the two styles. In the event-driven style we talk about something that has happened (or is happening) and in the Request/Response style we talk in terms of what we want to do. Each style has it’s merit and the style you choose will depend on the situation and the maturity of the partners involved in the service collaboration/data exchange.
Also notice that the event-driven example does not imply any type of response to the operation. Typically event-driven systems will be asynchronously designed and the service operations will reflect that.
Why Messages?
Messages allow us to encapsulate the data needed for the domain as well as data we may need because of technical requirements. Technical requirements may dictate that we have to log messages or protect messages in other ways (which could require message IDs, encryption keys, etc). By encapsulating data in a message we also leave room to include the technical requirements within the same message and keep our domain model free of technical bits that aren’t really part of the domain.
How do you name your service operations and messages?
Simon and I would love to hear. Leave a comment or tweet it!
People, Process, Policy: You Are Here
Nov 16th
For anyone working in IT you have doubtless encountered the non-technology forces that impact your IT implementations and deployments. In my experience those forces are comprised of three main entities People, Process, and Policy.
At the center of our concentric circles, which are both collaborating and competing forces, are your information systems. The realizations of the business processes, policies and people are provided by the abstractions of the systems that comprise the overall technical architecture. These systems are constantly being pushed, pulled, and shaped by the interactions of our three forces.
People
Business are made up of people, each of whom are there for different reasons. Some people want a paycheck, others like the work, and others are so aligned with the organization that is hard to see where the separation is. People work to implement and execute the processes of the business within the guidelines of the policies to fulfill the companies mission.
Process
Processes represent the series of business events which are accounted for, ordered, and reacted to in order to execute the businesses function. An order is received by the order system, inventory is checked, products are packaged and shipped to the customer. The process can be viewed through the lens of ordered steps or events, depending on how you want to model it. Either way, process is the stuff of business. It’s how things happen and what gets done when something unexpected happens.
Policy
Policy governs what is allowed to happen, what the acceptable responses are in a given situation and the general rules an IT system will implement. Rules as simple as “customer first and last name are required on orders” or decision structures as complicated as “if the customer is a preferred customer and they cancel their order then no re-stock fee is charged, unless the item was custom ordered. But if the order was over $2000 then a 10% restock fee is always applied.” Policy can often be the biggest pain point because people forget policies, do not understand them, or misinterpret them.
Competing Forces
At times, each of these elements will act as a hero or villain. The friction this causes can impact IT at all levels. People change, someone quits or gets promoted, processes might change or policies may be altered or dropped all together.
Collaborating Forces
Then sometimes, all three elements began to work in harmony. People are able to change policies and processes in a way that opens up new opportunities for IT solutions. People are able to embrace change for the promise it holds – optimizing processes, minimizing policies and driving business value through an optimized fulfilling of the businesses mission.
Which leads to the last element, not accounted for by this simple illustration.
Change
Change is that external force which pushes and pulls each of the three elements and causes them to collide or work together. Change is the constant in our equation; the market changes, technology changes, perspectives change. People, process, and policy – all change. Sometimes with each other, sometimes not.
This is where IT is and where we must be. Our job is to learn to roll with the changes and provide an architecture that meets the one constant – change. Our systems must be able to change and evolve as the people, process, and policies all change. Within those concentric circles lies that sweet spot and when we get even a glimpse of it, we know that we are right where we need to be.
Navigating the Map
What can you do now that you understand you are stuck in the middle? The answer is what separates the IT Pros from the rest. IT is not the solution to every problem because it is not sustainable for IT to be in the middle of everything. IT won’t always solve people problems, can’t always fix process problems, and often IT cannot change policies.
The key to be an effective member of an IT organization is to talk to the business about their problems, in their language. Leave the techno-babble at the door. Unless you are meeting with other IT teams, tone the language to your audience. The three forces of People, Process, and Policy are already affecting the business and introducing IT jargon in the middle isn’t going to solve those problems.
Listen. Talk to the business in their language. Suggest IT solutions when appropriate. Keep in mind that IT is not a hammer and there are some problems IT cannot solve alone.
NIEM National Training Event 2009 – Focus on Architecture; Focus on Community
Oct 5th
Chris Deweese shaking hands with Kshemendra Paul, Federal Chief Architect (Yes it was Friday and yes that is his @meshirt)
Photo Courtesy Christina Bapst, DHS (using Anthony Hoang’s awesome camera)
The 2009 NIEM National Training event took place from September 30th to October 2nd in Baltimore, MD. I had the honor of attending this years event and delivering two presentations over the three days of the conference. You can view all of the sessions on-line with a free registration here. The sessions were great; a mix of hands on, practical NIEM implementation as well as informational sessions on NIEM and NIEM tools. Instead of typing up a review of the three days of sessions I will skip to the final half-day because that is where the prior days were summed up and the lessons learned and shared really came to life.
The final half-day of the 2009 NIEM National Training Event was a town hall meeting with the IT leaders of this country. Federal CIO Vivek Kundra, Federal Chief Architect Kshemndra Paul, DHS CIO Robert Spires, DOJ CIO Vance Hitch, and DHS EDMO Director Donna Roy. Vivek delivered the closing keynote and the remaining group fielded questions from the audience regarding NIEM, information sharing politics, the implementers community, and more in a town hall style meeting.
The questions were pointed and the answers were open and candid. The group is aware of where things have fell short and aware of where NIEM has enabled the ability to deliver business value at all levels of government. Throughout the closing keynote and the town hall, all members of the panel hit on several key success factors.
Speak to the Business in Terms of Business Value and Not Fancy Technical Terms
The business does not speak your language, they do not speak Xml, NIEM, SOA, IEPD. But they do speak value, and cost savings, vision, and innovation. Speak to the business in those terms. Don’t silo your self by speaking in your language.
“Architecture is a 12-letter word for planning.” –Ksmendra Paul
This was *the* quotable moment for an architect listening to this group. This quote was spoken but Mr. Paul himself, and the others on the panel echoed his sentiments. As federal CIO Vivek Kundra put it, architecture must be used to solve real problems or it becomes an academic exercise. SOA is designed to solve real problems and handle real complexity and that is at the center of the strategies the federal government is using to enable information sharing, reduce costs, and put NIEM to use as the data model standard for federal enterprise projects. These leaders talked about SOA, the bus, and how they are using it to provide value to the American people, reduce IT costs, and remain agile.
NIEM Needs a Community for Implementers to Keep the Grass Roots Effort Going
In a question that took me 10 minutes to build up the nerve to ask, I asked what the plans are to build a community for the implementers because it is the implementers that can help drive NIEM adoption in a way that speaks to the grass-roots which started it. Donna Roy fielded the question and candidly put it that the NIEM committee knows they have not reached out using the best means; using one-way communication with a static website and monthly news-letter. Donna said they need to leverage Web 2.0 and help us collaborate better and that they are working on it. And during her answer Donna paid homage to my humble beginnings as the NIEM Guy, when I started blogging about NIEM because no one else was and I had questions.
Community is where the real connections happen. When I was in front of a room that was 80% full of .NET developers looking to see how to connect the dots of NIEM and .NET, I realized how much of a community we need; because there are many out there who just need some quick answers to point them in the right direction of best practices and how to handle various situations. We need a community that will be open and will bring people in. As Donna phrased it, we need to be more like open source communities.
My pledge to everyone that is part of the NIEM community is that though I am leaving .gov employment, I will remain a part of the community and continue to contribute where I can to help others succeed in bridging the gap in information systems.
Along with all this is a shout out to all the #NIEMNTE Tweeps (in no particular order and I am sorry if I miss some of you!) – let’s keep the tweets going for #NIEM and #NIEMNTE.
- Datachick
- Malawto
- Akprakas
- nmccready
- g_christensen
- NIEMIfy (whoever you are)
- NIEMExecDir (Donna Roy herself!)
- webbr
- Bluemont (thanks for the lift to BWI!)
- Jim_Cabral
- jbiala
- orand
- gotNiem
- CarlCNelson
- NIEMBizArch
- Kurt_Cagle
- JoelByford
… and all the others I missed. Keep the community going!
Integrating Existing Systems With NIEM Using SOA – Follow Up
Sep 30th
As I mentioned in the beginning of the presentation, what I presented was based off my experiences and opinions and was subject to change and during the great Q&A and discussion, I received some great feedback and experiences from others that helped refine and redirect a few opinions I expressed.
Regarding adapters and whether they belong to the bus or to the systems being adapted for the bus – I see a case for both, but, I think that ultimately when you reach a point that you are adapting so many systems and doing so many transformations it makes more sense for those to be a concern for the bus. Maintaining that many adapters in individual systems would become a burden over time; something that only experience would teach you and it’s an experience I’ve not yet had and may not at this point.
Thank you to everyone who attended and stayed for the Q&A. I got a lot out of the Q&A and definitely have a lot more to learn. This was something different for me to present because I know where I think projects could’ve been done better if I had accepted the bus as a viable solution and if I had the lens of designing systems to be more event-driven. I wanted to share that perspective but also open up to other perspectives because that is where I think the sharing of experience really provides value to all. Thanks to the 4B Track Lead Anthony Hoang of DHS for the humbling introduction and coaching prior to the presentation.
Many props to guys like Dru Sellers, Udi Dahan, and Chris Patterson who have helped shape some of my thinking on the bus and events. Definitely check out their projects, Mass Transit and NServiceBus, as real solutions for those of you on the .NET side of the fence who need a functional bus to enable your EDA.
Here are the slides – I know the conference staff will post them, but I caved in and paid for Internet in the room so I’m going to use up all the bandwidth I can
Service-Oriented, Event-Driven Part 2: Autonomous Services
Sep 29th
Last time we looked at events, notable changes in state, that can be used to notify other systems who may be interested in the event. We ended with some pseudo code showing examples of how it might look and finally with some thoughts on coupling, which is where we slide into part two.
What is an autonomous service? Firstly, let’s define autonomous – via Bing:
- self-governing: politically independent and self-governing
- able to choose: able to make decisions and act on them as a free and independent moral agent
- self-sufficient: existing, reacting, or developing as an independent, self-regulating organism
When we talk about autonomous services, what we mean are services that are self-governing, self-sufficient, and able to choose. Autonomous services are the gate-keepers to systems of record and exist on their own. Back to our pizza example we could feasibly have a kitchen service that exists on it’s own, independent of any specific order service. To put it Vegas style, “What happens in the Kitchen Management Service, stays in the Kitchen Management Service” (except when it’s an event we want people to know about…more on that later).
Autonomous services will be focused to a particular set of related tasks such as our Kitchen Management Service which monitors orders in being cooked and stock levels of products. I lean towards looking at a service through a single responsibility lens. The more focused you keep that service, the cleaner the abstraction remains and the easier it will be to integrate in an environment of collaborating services.
Autonomous services are self-contained and therefore internal implementations can change as needed. By keeping services focused and isolated we can reduce the coupling between other collaborating services or systems. The only thing an autonomous service must do is fulfill it’s contract. The contract is the definition of the abstraction the service is representing. Typically this is a WSDL in the web service world along with the accompanying schemas. But what we’re talking about here aren’t request-response services, so how does the contract apply in an event driven world?
This question opens the door to what we will explore in Part 3 of Service Oriented, Event Driven: Collaborating Services. Stay tuned!
Service-Oriented, Event-Driven Part 1: Events
Sep 13th
The real-world does not follow a linear, step-by-step process in order for things to occur. We may rationalize and tell ourselves that things happen in sequence and that ‘c’ won’t happen before ‘b’. We model our systems this way and we code this way because we view the world through this lens. I am beginning to fully believe that we must shatter this lens, because it colors the world with a perspective that doesn’t fit.
The real-world is disorderly, it is chaotic, and it is made up events – notable changes in state – that we must react to. The traffic light turns green, so you go, except the car in front of us isn’t going so now you can’t go. You order coffee and wait, and then the guy behind you gets his coffee first with yours ready a moment later.
Integrating systems using the lens of events is key to success, especially when the systems you are integrating are not yours or they belong to an entire other organization. This is where a firm understanding of the information being exchanged as well as when it will be exchanged becomes key.
Udi Dahan posted an article titled “Don’t Delete – Just Don’t” a few weeks back. In that article Udi explores soft deletes versus hard deletes, but he also raises another interesting thought that I’d like to build on. Our systems maintain the state of records over time. That state can be things like “entered”, “active”, “inactive”, “accepted”, “denied”, and whatever the business case may be. As I have already described events as notable changes in state, so what if we start looking at our systems records and the notable changes in state, what would we see?
Dru Sellers frames this in “Events Are Awesome” where he writes:
“I have also started to think about what it would mean to develop a system ‘event first’, and then you can look at what needs to be done when these events happen. It builds completely different systems, based on some initial drawings.”
Over the last few weeks I have been thinking about the same thing. So let’s hop on the example bus and see where it takes us.
Suppose we run a pizza delivery business and we’re going to automate what has been a manual process. At a high-level, we could see a few processes we need: Customers should be able to place orders, the kitchen needs to be able to be notified of orders so they can cook them, the delivery supervisor needs to know where orders are going so drivers can be scheduled, and the store manager needs to know about the volume of orders so that the financials can be reviewed. Skipping through the normal business analysis that needs to take place, we’ll say that we end up with four systems, each with a distinct job.
- The order system processes, validates, and accepts pizza orders from customers.
- The kitchen management system accepts orders, verifies stock levels, and notifies the cooks so the order can be prepared.
- The delivery scheduling system accepts orders, determines the route, and schedules a driver to deliver the order.
- The financial system accepts orders and records details about the underlying transaction amounts.
If we examine the order system using the events lens we can come up with some notable events: “Customer Submitted Order”, “Order Validated”, “Order Accepted”. With each one of these events a notable change in state has occurred and the information about that order should be communicated. For example, the delivery scheduling system might want to know about orders when they are validated because it takes longer to schedule a driver, whereas the kitchen management system might not want to know about orders until they are accepted so that ingredients are not used too soon in the process.
You may argue that this is not much different than procedural thinking. We could just code something to the effect of:
if (order.status == validated) {SendOrderToDeliverySystem(order);}
While that one line of code may be the simplest thing that could possibly work, what have we done? In essence, we have now coupled our order system to the delivery system. And this is where procedural thought begins to break down because that line of code is so specific that when we need to change it, the change has an effect that we may not fully understand especially because over time code becomes more complex as systems are expected to do more.
Consider the case where now the Kitchen System wants to know about orders when they are validated instead of accepted. We now have to refactor our one liner to something like:
if (order.status == validated)
{
SendOrderToDeliverySystem(order);
SendOrderToKitchenSystem(order);
}
Now consider if we used the .NET Framework’s notion of events:
public delegate void OrderValidatedEventHandler(PizzaOrder order);
public event OrderValidatedEventHandler OrderValidated;…{ //more code and curly braces }
if (order.status == validated && OrderValidated != null) {OrderValidated(order);}
If all of our systems were implemented as components with references to each other we could hook onto these events and reduce our codebase. But even then we still have a problem – coupling. Using direct references is a form of coupling that ties those components together. We can use Dependency Injection to reduce that, but then we still have the question to answer – what if each of our 4 systems comes from a different vendor?
In Part 2, we will discuss autonomous services and why we want to reduce coupling.


