Pattern for Plugins - IoC/DI or not? - c#

Just a very general question, that not only applies to this example.
Let's say you have an Online Shop and you want to implement Vouchers/Gift Certificates, but with Constraints. Let's say you have a voucher for 20% off, but that applies only to products added within the last 3 weeks, but not to ones in a special promotion.
I see two ways to solve it: The first way is to code your shop to "natively" support all crazy types of vouchers. This seems to be the classic way, but it means a lot of work beforehand and very little flexibility (After all, you can't know beforehand what you need, and maybe Sales may come up with some really great new promotion which requires new vouchers - by next Monday).
The second way is a Plug-In way: Vouchers are like Plugins and each Voucher has it's own Code. You pass in the Shopping Basket into the Voucher and then the Voucher itself checks each item if it applies, makes the neccessary changes and returns the changed shopping cart.
I just wonder, what is the Design Pattern for Case 2? It looks a bit like IoC/DI, but then again not really because Vouchers are not replacing any existing functionality. It's more like a set of Object with a Special Interface (i.e. IVoucher), and then a Queue of IVoucher Object that gets iterated over. Is there a standard pattern (and best practice) for these types of "Manipulators"?
Edit: Thanks for the Answers. To clarify that just a bit, the Vouchers (or Manipulators - as said, this is not only a question about online shops but about a similar situations) are "heavy" objects, that is they have Business Logic in them. So I can say that a Voucher only applies if the Customer signed up before January 1 2008, only if the customer ordered at least 100$ in the past 6 months, only applies to articles in the Category X, "stacks" with other Vouchers except for Items marked as Reduced etc. etc. etc. So my concern was more about how to keep a clean structure to make sure the Vouchers get all that they need to check whether they apply and to be able to manipulate the Cart, so I wondered about what the standard for such situations are, which is exactly what the Visitor Pattern seems to do.

It's a case where you could use the strategy pattern along with the vistor pattern to calculate the value of the basket.
A vistor could visit each item in the basket utilising different strategies (in this case discount vouchers) and using those to calculate the full cost of the basket.
The vouchers used could be retrieved from a database in some way and injected into the visitor quite easily.
The voucher strategy could look something like this:
public interface IVoucher
{
decimal CostOf(CartItem cartItem);
}
The default would be something like this:
public class FullPriceVoucher : IVoucher
{
public decimal CostOf(CartItem cartItem)
{
return cartItem.Cost;
}
}
A 10% discount would be something like:
public class TenPercentOffVoucher : IVoucher
{
public decimal CostOf(CartItem cartItem)
{
return cartItem.Cost * 0.9m;
}
}
Then you could have a visitor for calculating cart value like this:
public class CartValueVisitor
{
private IVoucher voucher;
public CartValueVisitor(IVoucher voucher)
{
this.voucher = voucher;
}
public decimal CostOf(Cart cart)
{
return cart.Items.Sum(item => voucher.CostOf(item));
}
}
Which you would use like:
var cart = GetACart();
var fullPriceCartValueVisitor =
new CartValueVisitor(new FullPriceVoucher());
var tenPercentOffCartValueVisitor =
new CartValueVisitor(new TenPercentOffVoucher());
var fullPrice = fullPriceCartValueVisitor.CostOf(cart);
var tenPercentOffPrice = tenPercentOffCartValueVisitor.CostOf(cart);
This obviously only works with a single voucher at a time but should give you an idea of the general structure.

The previous answers suggesting Visitor and Strategy patterns sound fine to me, although Visitor is overkill in the typical case where each purchase item is an object of the same concrete class. The purpose of Visitor is to allow dynamic dispatch on two (or more) object types -- the visited objects are part of one hierarchy, and the visitors are part of another. But if only one object type (the concrete type of the class implementing IVoucher) varies, then regular old single-type virtual dispatch is all you need.
In fact I personally wouldn't bother with any "pattern" at all -- your own description is exactly what's needed: create an interface, IVoucher, and a bunch of classes that implement that interface. You'll also need a factory method that takes a voucher code and returns an IVoucher object having the appropriate concrete type.
Beware Non-Commutative Vouchers!
The fact that you mention a queue of IVoucher-implementing objects will be run against the purchase items implies that more than one voucher may be used. In this case you need to be careful -- does applying voucher A, then voucher B always have the same effect as applying B then A? Unfortunately many typical "special offers" would seem not to have this property (e.g. if voucher A gives you $10 off and voucher B gives you 5% off, the order definitely matters).
A quick and dirty way out of this is to assign each voucher a distinct numeric "priority" value, and always apply vouchers in priority value order. To reduce the probability of "weird" combinations of vouchers driving you bankrupt, it's probably also a good idea to limit voucher combinations to some set of allowed combinations specified in your code somewhere. (This could be as simple as a list of lists of voucher codes.)

Maybe the Visitor pattern? The different types of vouchers are the visitors, which visit the shopping basket and manipulate it.
I don't think IOC is the solution here.

Related

Generate a unique ID to a body property of an object that's CONSISTENT through runtime and presents no overhead to the developer on implementation

This problem is a bit hard to expose via the title so I hope the following clarifies my intentions a bit.
Suppose you have the following data classes:
class abstract Employee {
string ID;
}
class FullTimeEmployee : Employee {
string schedule;
}
class PartTimeEmployee : Employee{
string schedulePartTime;
}
class WheelsSpecialist : Employee{ }
class InteriorsSpecialist : Employee{ }
class Workshop {
WheelsSpecialist wheely_guy;
InteriorsSpecialist interiors_guy;
}
Now, suppose that I instantiate my workshop as follows:
var Workshop = new Workshop{
wheely_guy = new PartTimeEmployee(),
interiors_guy = new FullTimeEmployee();
}
Please assume that the structure / inheritance and instantiations here provided are immutable.
What I'd like is to generate an ID set on Employee.ID that survives the runtime and is consist and independent from class properties / developer implementation.
Understand also that: The path of each object property in the workshop instantiation is guaranteed to be UNIQUE.
As so, a good ID for the WheelsSpecialist in Workshop.wheely_guy would be "Workshop.wheely_guy". (for example) because no path will ever be the same when I'm instantiating the workshop.
When I access the object "Workshop.wheely_guy.ID" I'd like to have "Workshop.wheely_guy" there or something analogous.
I imagine something like this would work (non valid C#, logic intact):
class PartTimeEmployee {
//instantiationPath is for example, "Workshop.wheely_guy"
onCreate(string instantiationPath){
this.ID = instantionPath;
}
}
I've tried this with StackTrace and whatnot, but couldn't find a way of doing it right.
Whether this instantiationPath method is used or not, the solution requires that:
I get to keep my structure as is in the example EXCEPT for properties. Those can change.
When I want to add a new dimension to my workshop variable I CAN'T, as a developer, be responsible for awarding a class it's own unique property.
As so, doing something like "this.ID = wheels" manually is not an option (also, depending this ID on properties that the developer must implement is also not viable).
Can this be done some way that meets my demands?
Thank you!
The provided code does not compile, and the object design/inheritance used seems a bit off. You probably want to work on the abstractions themselves. But that is not what you asked (mainly). It's kind of hard to figure out what exactly you asked, but I will do my best to answer what I think you asked (mostly):
"I want a field of an object instance to contain an automatically calculated navigation path by which it is accessible in some collection or composite object unrelated to the object itself" -> while close to impossible in C#, this might be entirely/easily possible in other languages. Still, the concept itself seems a little off.
The premise here is that the Employee object does not and should not know about the Workshop object Think about part-time employees trying to work separate shifts in separate workshops at the same time, and other possible changes in the business logic regarding Employees and Workshops.
Let's walk through some of the possibilities, ordered by viability:
Doing some magic at constructor/instantiation time in the abstract constructor code (Stack Frame walking, callerMember tricks, Reflection?, AST parsing?)
At instantiation, in a constructor, the stack trace does not contain information about which property/field it is about to be assigned to (if at all for that matter, it might just need to be instantiated, not assigned to anything). So there is no way to set such an id at constructor time.
Doing some magic in the Id property getter
There is no way to pass in parameters to a property getter, so we run into the same type of problem as with option 1: the stack trace contains no useful information by the time the getter is accessed.
Make the Employee object know about Workshop
No, just no.
Some weird runtime/weaving magic to "calculate" these paths when they are accessed?
Maybe, but how much effort to put in and to what purpose?
Expression parsing in a separate method:
//Left out the non-compiling code.
public static void Main(string[] args)
{
var Workshop = new Workshop
{
WheelsGuy = new PartTimeEmployee(),
InteriorsGuy = new FullTimeEmployee()
};
Console.WriteLine(GetObjectAccessPath((_) => Workshop.WheelsGuy));
}
public static string GetObjectAccessPath(Expression<Func<Workshop, Employee>> member)
{
string body = member.Body.Reduce().ToString();
// the line below might take some tweaking depending on your needs
return body.Substring(body.IndexOf($"{nameof(Workshop)}"));
}
// Output: Workshop.WheelsGuy
Use Reflection in a separate method to "get" a list of properties that are of any type derived from Employee and based on that Generate a list of ids with something like properties.Select(p => $"Workshop_{p.Name}");
Most viable: Re-design the object model:
(This is my opinion, and the requirements of your project might be different. Even if I am speculating here, the same principles presented here would apply in many other ways).
Extract more abstractions, like Position, Role, and Schedule. Part-time would be a schedule. Wheels guy would be a role. Position would be "an employee that fulfills the role of wheels guy at a workshop." There might be more examples (pay by hour/week/month, tax exemption, etc.).
As a rule, holding too many concerns in one class is a code smell and will get you in trouble quick. You can choose to carve up the classes however you want, but for what you "seem" to want, this part is important: have a class that represents the relationship between employee and workshop.
For example, instead of the Workshop holding instances of Employees: the Position class would hold/know about an Employee, his Role, his Schedule, and the Workshop he works at. The Position's Id could then easily be Id => $"Workshop_{Role}"; or Id => $"{WorkShop}_{Role}", etc. As a bonus, you get the design bonus of the Workshop being free from knowing which types of employees it might hold.
In general, I'd suggest you look into SOLID principles, it's an eye opener.

Multiple choice enum

I am lately starting a project and I have a question.
Let's say I am dealing with a class Person, and a person can have one(or more) deseases he is encountering.
so I have created an enum :
public enum diseases{headache,throat,bruise,gunshot,none}; // enum containing all the diseases
public diseases disease;
And further in code I set a certain disease to that person and it works fine.
Thing is, there might be a point in my project where a person might have 2 diseases.
So there are my questions:
Is using enum the best option here? I want my code to be organized and understood and that's a main reason for using enums.
If using enum is a good option, I have managed to combine this enum with bit-flags(using [System.Flags]) so when time comes I can check for a disease that contains two different values from the enum. is this a good approach?
If using enum is a good option, should I just create a second property from diseases (just like I created disease) and save all the trouble from using bit-flags?
Thanks in advance for any light on that matter, couldn't figure what was the best approach here.
A good option would to make a List<diseases> to hold for a single person.
public class Person
{
public string Name { get; set; }
public List<diseases> Diseases { get; set; }
public Person(string name)
{
this.Name = name;
Diseases = new List<diseases>();
}
}
This way you can enumerate over all the values relatively easily without having to worry about flags.
For example:
var bob = new Person("bob");
bob.Diseases.Add(diseases.gunshot);
var hasHeadache = bob.Diseases.Any(x => x == diseases.headache);
An enum is a plausible (yet a bit simplistic) way to represent one disease.
If someone may have N diseases, then just use a container of objects of that type, such as a list. But you need to choose the right container. A list of diseases may be, for example: { headache, throat, headache, throat, gunshot }. Lists allow duplicates. Whay you may actually need is a set of diseases. A set is a structure which does not allow duplicates.
The choice of how you represent one disease and the fact that a person may have N diseases, so that you need a person to have a container of diseases, are two totally independent facts.
Use the FlagsAttribute on your enum.
[Flags]
Public enum diseases
{
// your values here
}
This should give you what you need.
There is a lot of opinion being asked for here and the right answer is that it depends on a lot of variables what solution is right in any given situation. You CAN use an ENUM to represent multiple values so long as the [Flags] attribute is given to the ENUM. Keep in mind that if you decide to go that route then you are responsible for assigning the values of the ENUM specific non-overlapping values like 1, 2, 4, 8, 16, 32, etc.
Is using enum the best option here? - This depends on how many diseases you would like to cover. If the number is small (10..20) and the list is flat (no hierarchy of diseases) then you are fine. Otherwise, consider some alternative.
is [System.Flags] a good approach? - Yes, in case of a small, flat, list [System.Flags] approach is very good and extremely efficient.
Should I just create a second property from diseases and save all the trouble from using bit-flags? Having a second property in place of running a collection is a terrible idea. If you have to do something twice, chances are, you'd do it N times. Make a collection or bit fields, never go for a second property unless the system is inherently limited to two items (say, a binary tree).
If the list of diseases is not "flat" (e.g. you plan to have ViralThroat, BacterialThroat, and ThroatInjury in place of a simple throat that you have now) you would be better off modeling diseases as classes, and creating a collection of diseases attached to a Person. You could add methods for checking the collection for particular diseases, which could be smart about the search: for example, find any kind of throat sub-disease when a throat is passed as a search criterion.
enum is just one of many perfectly acceptable options here. Others include OO solutions such as base/derived classes, or simple lists of string (or event lists of enums, why not?!). Often the simplest approach is best. We would have to know a lot more about your problem to recommend one over the other.
While using Flags is one solution, I would not recommend it in this case. Flags are not verbose on what they are for. Any time I used flags, I would have to re-learn how to properly work with flags when I needed to modify my code. One simple alternative is creating a property for each possible disease...
public class Diseases
{
public bool Headache {get;set;}
...
public bool HasAnyDisease() { return Headache || Throat || ...;}
}
But that has it's downsides as well. It's not easily extensible. I would recommend using the Decorator Pattern. Each disease could decorate the class which may make future interactions with it easier to maintain. If you need to have variance disease combinations cause different outcomes, this may be better in the long run.

Routing an object in C# without using switch statements

I am writing a piece of software in c# .net 4.0 and am running into a wall in making sure that the code-base is extensible, re-usable and flexible in a particular area.
We have data coming into it that needs to be broken down in discrete organizational units. These units will need to be changed, sorted, deleted, and added to as the company grows.
No matter how we slice the data structure we keep running into a boat-load of conditional statements (upwards of 100 or so to start) that we are trying to avoid, allowing us to modify the OUs easily.
We are hoping to find an object-oriented method that would allow us to route the object to different workflows based on properties of that object without having to add switch statements every time.
So, for example, let's say I have an object called "Order" come into the system. This object has 'orderItems' inside of it. Each of those different kinds of 'orderItems' would need to fire a different function in the code to be handled appropriately. Each 'orderItem' has a different workflow. The conditional looks basically like this -
if(order.orderitem == 'photo')
{do this}
else if(order.orderitem == 'canvas')
{do this}
edit: Trying to clarify.
I'm not sure your question is very well defined, you need a lot more specifics here - a sample piece of data, sample piece of code, what have you tried...
No matter how we slice the data structure we keep running into a boat-load of conditional statements (upwards of 100 or so to start) that we are trying to avoid
This usually means you're trying to encode data in your code - just add a data field (or a few).
Chances are your ifs are linked to each other, it's hard to come up with 100 independent ifs - that would imply you have 100 independent branches for 100 independent data conditions. I haven't encountered such a thing in my career that really would require hard-coding 100 ifs.
Worst case scenario you can make an additional data field contain a config file or even a script of your choice. Either case - your data is incomplete if you need 100 ifs
With the update you've put in your question here's one simple approach, kind of low tech. You can do better with dependency injection and some configuration but that can get excessive too, so be careful:
public class OrderHandler{
public static Dictionary<string,OrderHandler> Handlers = new Dictionary<string,OrderHandler>(){
{"photo", new PhotoHandler()},
{"canvas", new CanvasHandler()},
};
public virtual void Handle(Order order){
var handler = handlers[order.OrderType];
handler.Handle(order);
}
}
public class PhotoHandler: OrderHandler{...}
public class CanvasHandler: OrderHandler{...}
What you could do is called - "Message Based Routing" or "Message Content Based" Routing - depending on how you implement it.
In short, instead of using conditional statements in your business logic, you should implement organizational units to look for the messages they are interested in.
For example:
Say your organization has following departments - "Plant Products", "Paper Products", "Utilities". Say there is only one place where the orders come in - Ordering (module).
here is a sample incoming message.
Party:"ABC Cop"
Department: "Plant Product"
Qty: 50
Product: "Some plan"
Publish out a message with this information. In the module that processes orders for "Plant Products" configure it such that it listens to a message that has "Department = Plant Products". This way, you push the onus on the department modules instead of on the main ordering module.
You can do this using NServiceBus, BizTalk, or any other ESB you might already have.
This is how you do in BizTalk and this is how you can do in NServiceBus
Have you considered sub-typing OrderItem?
public class PhotoOrderItem : OrderItem {}
public class CanvasOrderItem : OrderItem {}
Another option would be to use the Strategy pattern. Add an extra property to your OrderItem class definition for the OrderProcessStrategy and use a PhotoOrderStrategy/CanvasOrderStrategy to contain all of the different logic.
public class OrderItem{
public IOrderItemStrategy Strategy;
}
public interface IOrderItemStrategy{
public void Checkout();
public Control CheckoutStub{get;}
public bool PreCheckoutValidate();
}
public class PhotoOrderStrategy : IOrderItemStrategy{}
public class CanvasOrderStrategy : IOrderItemStrategy{}
Taking the specific example:
You could have some Evaluator that takes an order and iterates each line item. Instead of processing if logic raise events that carry in their event arguments the photo, canvas details.
Have a collection of objects 'Initiators' that define: 1)an handler that can process Evaluator messages, 2)a simple bool that can be set to indicate if they know what to do with something in the message, and 3)an Action or Process method which can perform or initiate the workflow. Design an interface to abstract these.
Issue the messages. Visit each Initiator, ask it if it can process the lineItem if it can tell it to do so. The processing is kicked off by the 'initiators' and they can call other workflows etc.
Name the pieces outlined above whatever best suits your domain. This should offer some flexibility. Problems may arise depending on concurrent processing requirements and workflow dependencies between the Initiators.
In general, without knowing a lot more detail, size of the project, workflows, use cases etc it is hard to comment.

Voyage, Booking, BookingService - Where to put capacity check

I'm new to domain driven design and would like to hear your thoughts on a design decision:
In my domain, I have the entities "voyage" and "booking".
The constructor for voyage looks like this:
public Voyage(VoyageNumber voyageNumber,
Schedule schedule,
IList<VoyagePrice> voyagePrices,
Location location,
Capacity capacity)
The value objects "voyagePrices" contain information about the price for a certain person type (child, adult, etc.). The capacity contains the maximum number of persons allowed on the voyage.
The constructor for the "Booking" looks like this:
public Booking(BookingNumber bookingNumber,
Customer customer,
Voyage voyage,
IList<ConfirmedPerson> confirmedPersons)
confirmedPersons contains the list of persons one customer wants to book (i.e. 2 adults, 1 child). Now, it is of course required to check the capacity of the voyage before allowing the booking to be saved. I dont think that "voyage" should contain a list of all the bookings made. Would it be okay to check the capacity in a BookingService or in a BookingFactory? Do you have any suggestions, maybe with a small code snippet? Thank you!
It completely possible and valid to have an available capacity be part of a Voyage or a boolean encapsulation like
Voyage.isFull()
Upon retrieval of a specific voyage aggregate from a VoyageRepository this information could be obtained.
However it's not enough, there's always a chance the voyage fills up after you've retrieved it from the VoyageRepository. So you will need to handle that exceptional case, maybe like
public interface BookingService {
Booking book(BookingRequest br) throws VoyageIsFullException;
}
And you'd probably want a BookingRequestFactory
public class BookingRequestFactory {
public static BookingRequest create(Voyage v, Customer c, IList<Person> travelers)
}
BookingRequestFactory can do some basic validation but not all cause the logic of whether it's full or not will probably require collaboration beyond what'd you'd want in a Object Factory, and is probably best handled by a BookingService.
if i anderstood you right you have to connect the two entities. I would suggest you do it just like it would be done in a relational database. Browse to this link: relational database design and read the paragraph: "Many-to-Many Relationships", i think this could be a solution :-)

Is this way of using Dictionary<enum,object> correct in this Production Planning example?

Consider a production planning application with many products. Each product has a list of InventoryControl objects keyed on InventoryControlType. Depending on the algorithm we run for production planning, we need to access to different types of InventoryControl objects for a given product. This works OK. However, today I needed to introduce a field in InventoryControl that holds the InventoryControlType since deep in our algorithms we needed to know the InventoryControlType.
However, I felt felt like I was doing something wrong since it looks like I am repeating data.
Does this design look OK to you? Any ideas for improvement?
class Product{
Dictionary<InventoryControlType, InventoryControl> InventoryControls;
GetInventoryControl(InventoryControlType type){
return InventoryControls[type];
}
}
class InventoryControl{
InventoryControlType controlType;
float limit;
float cost;
...
CalculateCost(){...}
GetConstraint(){...}
}
I think you're fine. It's perfectly normal (at least in my experience) to use a unique property of an object as a key--be it in a Dictionary, a DataTable, or what have you.
For example in my own work our major project features a class called Product with a property called Symbol, and the application maintains a Dictionary called Products with each Product object's Symbol property serving as its key.
Think of it this way: if you have a database with two tables, and one table references rows in the other by key, it may feel like you are "duplicating" data in the sense that you have the same number (the key) in two places. But that is not duplication; it's a reference. The same applies in your scenario.
I don't see anything inherently wrong with it. It is duplicating a piece of information, but the situation does call for it. You could use a normal collection instead of a Dictionary--but because your main goal is to find a piece of information based on its InventoryControlType, Dictionary, with this implementation, seems most correct.
I think it's absolutely fine for a Dictionary<TKey, TValue> use case.
Many times Dictionary objects will always have some sort of redundant information from the value object, the most common of which will be an ID, e.g. Dictionary<int, SomeObject> where int will be a value taken from SomeObject.Id -- it makes sense in that respect, and it's perfectly identical to your use case.
It really depends on how big the dictionary is supposed to get, because for very large amounts of data, I think the lookup on the dictionary using the key would probably be faster. But if you don't have very large amounts of data, you could use Linq and a Generic List. For example:
class Product{
List<InventoryControl> InventoryControls;
GetInventoryControl(InventoryControlType type){
return InventoryControls.First(x => x.ControlType == type);
}
I would recommend running some unit test benchmarks to see whether the Dictionary is required.

Categories