How to implement interchangeable/switchable business logic [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Lets say I have 3 tasks: Registration, Assessment, Enrollment.
I want to be able to make my application have these 3 interchangeable in position in the process. So for one setting, I can do Registration -> Assessment -> Enrollment. I can change for another setting to Registration -> Enrollment -> Assessment.
And also I need to be able to switch on/off some functionality of task (like Registration).
Can you guys give me an idea of where to start?

I would set up a chain of responsibility. From GoF:
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
Here's a barebones example that uses the names of business processes you've given:
// These all should be named something relevant to your domain
public interface IHandler
{
void Handle(string request);
}
public class Handler
{
protected IHandler successor;
protected Handler(IHandler successor)
{
this.successor = successor;
}
protected virtual void Successor(string request)
{
successor?.Handle(request);
}
}
public class Registration : Handler, IHandler
{
public Registration(IHandler successor)
: base(successor) { }
public void Handle(string request)
{
Console.WriteLine($"Registration handled request {request}");
base.Successor(request);
}
}
public class Enrollment : Handler, IHandler
{
public Enrollment(IHandler successor)
: base(successor) { }
public void Handle(string request)
{
Console.WriteLine($"Enrollment handled request {request}");
base.Successor(request);
}
}
public class Assessment : Handler, IHandler
{
public Assessment(IHandler successor)
: base(successor) { }
public void Handle(string request)
{
if (request.Equals("Bob", StringComparison.InvariantCulture))
{
Console.WriteLine("Bob failed assessment.");
return;
}
Console.WriteLine($"Assessment handled request {request}");
base.Successor(request);
}
}
and example use:
// Consumers of this don't need to know anything more than it's an IHandler service
// Consumers of this don't need to know anything more than it's an IHandler service
IHandler noregistrationHandlers = new Assessment(new Enrollment(null));
// or Autofac
// builder.Register(c => new Assessment(c.Resolve<Enrollment>(null))).Named("NoRegistration");
// or your favorite IoC container
noregistrationHandlers.Handle("Smith");
IHandler registrationHandlers = new Registration(new Assessment(new Enrollment(null)));
// builder.Register(c => new Registration(c.Resolve<Assessment>(c.Resolve<Enrollment>(null)))).Named("Registration");
registrationHandlers.Handle("Bob");
Here's the takeaway on this - the consuming code (the usage example) doesn't need to know anything except the format to send the request to the handler. The fact that the constructors are invoked in the example is a matter of mere convenience for example's sake. You can very well have an MVC controller that depends on an IHandler but knows nothing else about it.
public class UserController
{
private readonly IHandler handler;
public UserController(IHandler handler)
{
if (handler == null) throw new NullReferenceException(nameof(handler));
this.handler = handler;
}
// ...
public ActionResult Save(string id)
{
handler(id);
}
}

Related

Virtual void not being overridden with override keyword in C# [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I am trying to make a class the user of my library can derive from and then access a method for debugging the times of each action. Because my main debug method, where most information is stored, is static (and needs to be), I cannot use it to derive a class or add an overridable method in it. To combat this, I added the following code:
public static class Debug
{
internal static void CallObjectEvent(string log)
{
new Call().CallEvent(new Log(log, Timer.GetTime()));
}
}
internal class Call : IDebug
{
internal void CallEvent(Log log)
{
base.Event(log);
}
}
public class IDebug
{
public virtual void Event(Log log) {Console.WriteLine("test");}
}
class Program : IDebug
{
public override void Event(Log log)
{
Console.WriteLine(log.log);
}
}
Every time, it outputs 'test' instead of the log message. How can I fix this? Are there any alternatives to do the same thing?
Your Debug.CallObjectEvent() method explicitly instantiates a Call object and calls the overridden method in that class:
public static class Debug
{
internal static void CallObjectEvent(string log)
{
new Call().CallEvent(new Log(log, Timer.GetTime()));
}
}
The CallEvent() method in the Call class simply calls base.Event(), which resolves to IDebug.Event(). The Program.Event() override is never invoked because Program is not in the class hierarchy at the point of the call.
When you override a method or property, the override applies only to the class where it is defined (and all of its child classes, of course). Since Program isn't a parent class of Call there's no reason why its overrides would ever be referenced.
From what you've written it looks like you're trying to set up a system for handling different log outputs depending on the program's requirements. You need a way to register the appropriate log writer for your program. Something like:
public interface ILogWriter
{
void Event(Log item);
}
private class DefaultLogWriter : ILogWriter
{
public void Event(Log item)
{
Console.WriteLine($"[test] {item.Time} {item.Message}");
}
}
internal static class Debug
{
private static ILogWriter _writer = null;
public static ILogWriter Writer
{
get
{
if (_writer == null)
_writer = new DefaultLogWriter();
return _writer;
}
set => _writer = value;
}
internal static void CallObjectEvent(string log)
{
Writer.Event(new Log(log, Timer.GetTime()));
}
}
class Program
{
private class MyLogWriter : ILogWriter
{
public void Event(Log item)
{
Console.WriteLine($"[MyLogWriter] {item.Time} {item.Message}");
}
}
static void Main()
{
Debug.Writer = new MyLogWriter();
Debug.CallObjectEvent("Test message.");
}
}

Event dispatching library with IoC

In the past I've built a MessageDispatcher component that scans an assembly for types decorated with certain attributes and initializes an instance of each. Then, when any object is fed to the MessageDispatcher instance, every previously initialized instance which contains a method which signature contains the type of the passed object has said method triggered with the specified parameter. For example, in a scenario like:
[Listener]
public class MyListener
{
MessageDispatcher _dispatcher; //Assigned elsewhere
[MessageListener]
public async Task DoSomething(int value)
{
var otherValue = await _dispatcher.Next<string>();
Console.WriteLine($"{value} is {otherValue}.");
}
}
The following code initializes an instance of the MyListener class, calls DoSomething and prints "7 is okay.":
var listener = new MessageDispatcher(typeof (ListenerAttribute));
listener.Dispatch(7);
listener.Dispatch("okay");
I would like to know if there are any libraries out there that are dedicated to or include a service like such. It has to be able to:
Scan assemblies and initialize types based on an attribute.
Dynamically "subscribe" to certain types
"Wait" on a value to be pumped from the dispatcher (like with the Next method in my example).
(as library recommendations is not allowed per the SO rules, here is an attempt to instead answer with an implementation)
You can get that with virtually any IoC. All they need is to be able to register services using an attribute or some other conventional way.
As for the message dispatching. Just create an interface like IMessageHandler<TMessage>. Implement it on all classes that should handle messages.
Example:
public interface IMessageHandler<TMessage>
{
void Handle(TMessage msg);
}
public class SomeService : IMessageHandler<UserCreated>
{
//[.. all other methods ..]
public void Handle(UserCreated msg)
{
// ...
}
}
To publish messages you create a dispatcher. Since you use a container you do not have to make it static. Use your container inside it (service location) to dispatch the messages. Now some peeps might say oohh no, service location is anti-pattern, buhuhuhu. Well no. Not in all cases. In this case it's an implementation details in a class with the specific purpose to identify and invoke other classes.
public interface IMessageDispatcher
{
void Dispatch<TMessage>(TMessage msg);
}
// The actual implementation differs
// depending on your choice of container.
public class ContainerBasedMessageDispatcher : IMessageDispatcher
{
Container _container;
public ContainerBasedMessageDispatcher(Container container)
{
_container = container;
}
public void Dispatch<TMessage>(TMessage message)
{
using (var scope = container.BeginLifetimeScope())
{
var handlers = scope.Resolve<IEnumerable<IMessageHandler<TMessage>>();
foreach (var handler in handlers)
{
handler.Handle(message);
}
}
}
}
The code is written directly in SO. So it might not work as-is. But hopefully it's given you an idea how to achieve what you want.
Usage:
public class UserService
{
IMessageDispatcher _dispatcher;
public UserService(IMessageDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
public void Create(User user)
{
//[...]
_dispatcher.Dispatch(new UserCreated(user.Id));
}
}
this do however not dynamically allow you to subscribe on what you want. If just ignoring unwanted messages is not feasible. Then this answer is not for you.

Reprinting from an application with Command/Decorator Pattern and Simple Injector

So i am using a decorator to print after certain commands are handled. My issue is if the user wants to issue a reprint. I created a Reprint command class that gets sent from the UI layer, but the Reprint command does not need a separate handler from the PrintDecorator since the reprint handling is exactly everything in the print decorator. Is there a strategy to target the PrintDecorator only with SimpleInjector? I know this probably goes against the pattern, but the only way I could think of was to create an empty command handler for the reprint command, but that does not seem right. Thanks.
public class Reprint : ICommandParam, IPrintFrom
{
public string Id { get; set; }
public string Printer { get; set; }
public int Copies { get; set; }
}
public class PrintDecorator<TCommand> : ICommandHandler<TCommand>
where TCommand : IPrintFrom
{
private readonly IFooService _svc;
private readonly ICommandHandler<TCommand> _handler;
public PrintDecorator(IFooService svc, ICommandHandler<TCommand> handler)
{
if (svc == null)
throw new ArgumentNullException("IFooService");
_svc = svc;
_handler = handler;
}
[Import] // optional
public IDatabase Database { get; set; }
public void Handle(TCommand commandParm)
{
if (_handler != null)
_handler.Handle(commandParm);
svc.GetDataFromService(commandParm.id);
svc.PrintData(commandParm.Printer, commandParm.Copies);
if (Database != null && commandParm.Copies > 0) {
// TODO - add a print record
}
}
}
It all depends on what you want. My suggestion is to keep the reprinting logic inside a real ReprintCommandHandler (probably by injecting a service that does the printing the same way you would do with the decorator). This seems reasonable to me, because in the case of reprinting, the reprinting is the actual business logic, and not a cross-cutting concern.
In this case you will have to exclude the PrintDecorator from being decorated around your ReprintCommandHandler and this can be done as follows:
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(PrintDecorator<>),
c => c.ServiceType != typeof(ICommandHandler<Reprint>));
If on the other hand, you want to keep the printing logic inside the PrintDecorator without having to duplicate this logic inside your business layer, you can either implement a completely empty ReprintCommandHandler, or you can register a special Null Object command handler.
Using the empty handler is of course Simple and will make your configuration really straightforward:
// NOTE: Use RegisterManyForOpenGeneric for Simple Injector v2.x
container.Register(typeof(ICommandHandler<>),
new[] { typeof(ICommandHandler<>).Assembly });
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(PrintDecorator<>));
Downside is of course that you need an empty class for this. So the alternative is to implement the Null Object pattern as follows:
public class NullCommandHandler<T> : ICommandHandler<T> {
public void Handle(T command) { }
}
This implementation can be reused in case you have multiple empty implementations and you can register this as follows:
// NOTE: Use RegisterManyForOpenGeneric for Simple Injector v2.x
container.Register(typeof(ICommandHandler<>),
new[] { typeof(ICommandHandler<>).Assembly });
container.Register<ICommandHandler<Reprint>, NullCommandHandler<Reprint>>();
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(PrintDecorator<>));

Which code is better programming style

I have several different objects, but I have to do similar actions with them.
What is better to use:
1. Several methods and use these objects as type parameters.
2. Use one method which gets System.Object as parameter. And inside this method I will check type of parameter and do some action.
For example I should send notifications for some actions. I have objects Action1, Action2, Action3...ActionN, which contain details of these actions. Should I use:
public void SendNotificationForAction1(Action1 action) {}
public void SendNotificationForAction2(Action2 action) {}
public void SendNotificationForActionN(ActionN action) {}
or
public void SendNotification(Object action)
{
//here I will check type of action and do something
}
I guess it depends:
Is the code to send notifications more or less the same? Then I would opt for:
public void SendNotificationFor<T>(T action) {}
otherwise I'd probably choose to overload the method:
public void SendNotification(Action1 action) {}
public void SendNotification(Action2 action) {}
public void SendNotification(ActionN action) {}
The first one is type-safe, the second one is not. Therefore, if I 've to choose between those two options, I'd chose the first one.
On the other hand, isn't it possible to go with an entirely different approach ?
Where you have one base-class or interface Action, where other classes derive from ?
The interface or base-class could have a 'GetDetailsForNotification' method, which you implement in the implementors, and you can use that method in the SendNotificationForAction method.
something like this, but, offcourse, I do not know if this is viable in your context:
interface IAction
{
string GetDetailsForNotification();
}
public class Action : IAction{
public string GetDetailsForNotification()
{
return "details from Action";
}
}
public class Action2 : IAction{
public string GetDetailsForNotification()
{
return "details from Action2";
}
}
public void SendNotificationForAction(IAction action) {
var details = action.GetDetailsForNotification();
...
}
The Strategy Pattern may fit here too:
private interface INotificationStrategy<T> // or non-generic with object
{
void SendNotification(T action);
}
public class StringNotificationStrategy : INotificationStrategy<string>
{
public void SendNotification(string action)
{
throw new NotImplementedException();
}
}
A Factory could provide you the correct implementation, and you could provide further implementations without breaking existing interfaces...
I would go with the first approach.
It entails creating more methods, and possibly a bit more code, but I believe it to be much easier to use and typesafe.
Your second approach doesn't allow me to know in compile time what kind of Object the method is expecting without reading the code (imagine you distribute this code to be used as a library), and if I pass the wrong method, the only thing you can do is to make it fail in runtime - not great.
You should try to keep the method as generic as possible.
The SendNotification method could be built like this:
public void SendNotification<T>(T action) where T : SpecialAction {
}
The class/interface SpecialAction can then have methods that are different between the actions. For instance:
[abstract class] [interface] SpecialAction {
public string GetName();
public bool CanDoX();
}
As guys said, it depends, but generally I prefer variation(below) of 2nd approach, cause of it's easier to extend in future(of course, if you need).
interface ISendNotificationHandler
{
Type ActionType { get; }
void SendNotification(object action)
}
class Action1SendNotificationHandler : ISendNotificationHandler
{
public Type ActionType {get{return typeof(Action1);}}
public void SendNotification(object action)
{
Action1 a = (Action1)action;
// TODO: send notification
}
}
// your method originally posted
public void SendNotification(Object action)
{
var handlers = new ISendNotificationHandler[]{ new Action1SendNotificationHandler(), /* etc*/}
//
var handler = handlers.FirstOrDefault(h=>action.GetType().IsSubclassOf(h.ActionType))
if(handler != null)
{
handler.SendNotification(action);
}
else
{
throw new Exception("Handler not found for action " + action);
}
}
Have you considered using Observer Pattern
Wiki Link is here.
To keep it short, lets say you have subscribed to a news paper, when ever there is a new edition(event) of news paper, the subscriber will get notified and the new version is delivered.
here is my try :
Every ActionN class is derived from base Action :
class Action1: Action, INotify
{
public void override SendNotification() {...}
}
If some notifications have common implementation then have it in Action class.
Now in the class who sends notification do this :
class Sender
{
public void SendNotif(INotify actn)
{
actn.SendNotification();
}
}
And send proper object to SendNotif() method.

Recommend a design pattern [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 months ago.
Improve this question
An application I'm working on processes Work Items. Depending on the state of a work item there are a number of actions available. "Complete" "Cancel" "Reassign" etc...
To provide the functionality for the actions I currently have an interface that looks something like this...
public interface IActionProvider{
public void Complete(WorkItem workItem);
public void Cancel (WorkItem workItem);
public void Reassign(WorkItem workItem);
}
Then based on other details of the work item I have concrete implementations of the interface. Just for example...
public class NormalActionProvider :IActionProvider
{
...
}
and
public class UrgentActionProvider : IActionProvider
{
....
}
The problem is, if I want to add a new action, say... "Delegate" I have to update the interface which of course has effects on all of the implementations.
Does this violate the Open/Close Principle? Can you recommend a design pattern or refactor that may help me here?
Looks like command pattern would be suitable. You can modify/add more commands. The command classes are decoupled from the main program.
public interface IActionProvider{
public void execute(WorkItem item,ActionType actionType);
}
ActionType represents Complete,Cancel & so on. You can keep adding more action types & plugin appropriate command classes.
You could always add a Decorator to the IActionProvider interface (follow the Decorator design pattern).
It depends on what you really are trying to accomplish with your IActionProvider. If you really want to make it so that every implementation must be able to perform all of the actions that you consider to be important, then that should be a part of the interface that they implement. Interfaces work best if they are well-planned ahead of time so they don't have to change continually.
But it sounds like you don't necessarily want all actions to be implemented by all providers. I'd need to know more details to be able to give good advice, but one example would be to have the providers initialize themselves against a kind of event Bus. They could subscribe to those events that they care about, and perform actions only for the events that make sense for the specific implementation.
"Depending on the state of the workitem", brings the State Design Pattern
One way or another, you'll have to refactor you interface and eventually break client contracts.
If i have understood your problem correctly, then you have a WorkItemProcessor whose state changes depending
on the WorkItem Sent to it.
Therefore your WorkItemProcessor becomes
// Context
public class WorkItemProcessor
{
public IState CurrentState { get; set; }
public WorkItemProcessor(IState initialState)
{
CurrentState = initialState;
}
public void Process(WorkItem workItem)
{
CurrentState.Handle(this, workItem);
}
}
Then we define multiple states that the WorkItemProcessor could potentially be in
// State Contract
public interface IState
{
void Handle(WorkItemProcessor processor, WorkItem item);
}
// State One
public class CompleteState : IState
{
public void Handle(WorkItemProcessor processor, WorkItem item)
{
processor.CurrentState = item.CompletenessConditionHoldsTrue ? (IState) this : new CancelState();
}
}
// State Two
public class CancelState : IState
{
public void Handle(WorkItemProcessor processor, WorkItem item)
{
processor.CurrentState = item.CancelConditionHoldsTrue ? (IState) this : new CompleteState();
}
}
Assuming your WorkItem Looks like
// Request
public class WorkItem
{
public bool CompletenessConditionHoldsTrue { get; set; }
public bool CancelConditionHoldsTrue { get; set; }
}
To put it all together
static void Main()
{
// Setup context in a state
WorkItemProcessor processor = new WorkItemProcessor(new CancelState());
var workItem1 = new WorkItem { CompletenessConditionHoldsTrue = true };
var workItem2 = new WorkItem { CancelConditionHoldsTrue = true };
// Issue requests, which toggles state
processor.Process(workItem1);
processor.Process(workItem2);
Console.Read();
}
Hope this gets you closer. Cheers.
I would also choose the command pattern. As an enhancement, you can combine it with the abstract factory method, so you can have a factory class for each command class, and all those factories implement a common factory interface.
For example:
// C#
public interface ICommand { void Execute(); }
public interface ICommandFactory { ICommand Create(); }
public class CommandFactoryManager
{
private IDictionary<string, ICommandFactory> factories;
public CommandFactoryManager()
{
factories = new Dictionary<string, ICommandFactory>();
}
public void RegisterCommandFactory(string name, ICommandFactory factory)
{
factories[name] = factory;
}
// ...
}
This way, you can register new command factories dynamically. For example, you can load a DLL at runtime and fetch all the classes that implement the ICommandFactory interface using reflection, and you have a simple plugin system.

Categories

Resources