Context and Facets
A part of designing a method-based system is detailed design. So, once you have defined the service components, it is time to define the contracts.
Context
In searching for volatilities in your system you have probably found some parts that depend on the context in which they are executed. What does that mean?
How I like to explain it is, that context is about achieving the same result but from a different perspective. Like canceling a doctor's appointment.
Imagine a healtcare manager contract with the following operations:
public interface IHealthcareManager
{
Task<CreateAppointmentResult> CreateAppointment(CreateAppointmentRequest request);
Task<CancelAppointmentResult> CancelAppointment(CancelAppointmentRequest request);
}
Canceling an appointment in the context of a patient is likely to be different than when the doctor's assistant cancels the appointment. And with different I mean; it will involve less or more steps in the process. One obvious difference in the cancellation of the appointment by the doctor, is that the patient has to be informed and the appointment has to be rescheduled.
Context can be supplied separately from the method call. Like a security context that is passed in the header of a message, or a user context that is fetched via an authorization token.
Then, based on the context, the operation will perform less or more steps to complete.
There are several ways to supply the context, which I won't address in this post. That's something for a future post.
Facets
You do not want a service to have too many operations. This is not maintainable. A facet can be used to reduce the number of operations of one (God) contract. It is about separating use cases that do not really belong together but are executed by the same component/service.
For instance, the healthcare manager handles appointments on the one hand, and can find a qualified specialist/doctor for a patient's ailment on the other.
This leads to two facets. The IHealthcarePlanningManager and the IHealthcareMarketManager. And you can probably guess, the planning manager is all about handling appointments and the market manager is all about matching patients and doctors.
The end results
In this example the manager will have to implement two interfaces. The client will call the service by one of the interfaces.
Service
public class HealthcareManager :
IHealthcarePlanningManager, IHealthcareMarketManager
{
...
public Task<CancelAppointmentResult> CancelAppointment(
CancelAppointmentRequest request)
{
var strategy = _strategy.Find<IHealthcarePlanningManager>(_context);
return await strategy.CancelAppointment(request);
}
...
}
Client
public class HealthcareClient
{
public async Task<bool> CancelAppointment(guid appointmentId)
{
var proxy = _proxy.For<IHealthcarePlanningManager>();
var cancellation = await proxy.CancelAppointment
(
new CancelAppointmentRequest(appointmentId)
);
return cancellation.Approved;
}
}
Comments
Post a Comment