I'd like to know what is the best way to avoid repeating some recuring code structure by using Generics Func or any other way.
As a practical example let's I need to call 20 different WCF methods but I would like to have on code to handle exception.
Let's say this is the wcf proxy
class ClassWithMethodsToCall // say wcf proxy
{
public Out1 GetOut1(In1 inParam) { return null; } // would have some spesific implementation
public Out2 GetOut2(In2 inParam) { return null; }
public Out3 GetOut3(In3 inParam) { return null; }
}
class Out1 { } // some specific data structure
class In1 { } // some specific data structure
class Out2 { } // some specific data structure
class In2 { } // some specific data structure
class Out3 { } // some specific data structure
class In3 { } // some specific data structure
I created the following to have the one single error handling
class CallerHelperWithCommonExceptionHandler
{
public Tout Call<Tout, Tin>(Tin parameters, Func<Tin,Tout> wcfMethodToCall)
{
try
{
return wcfMethodToCall(parameters);
}
catch (Exception ex)
{
// do what ever
throw;
}
}
}
And I use it:
var callerHelper = new CallerHelperWithCommonExceptionHandler();
var theFunctionsToCall = new ClassWithMethodsToCall();
var in1 = new In1(); // init as appropriate
var ou1 = callerHelper.Call<Out1, In1>(in1, theFunctionsToCall.GetOut1);
var in2 = new In2(); // init as appropriate
var ou2 = callerHelper.Call<Out2, In2>(in2, theFunctionsToCall.GetOut2);
// and so on
Is there a better more elegant way? Alternatives in object oriented way, Template Design Pattern?
Thanks, al
It looks like you are adding code to implement a cross-cutting concern to a class (e.g. logging exceptions), so you might want to use the decorator pattern.
For example:
class Out1 { }; // some specific data structure
class In1 { } // some specific data structure
class Out2 { } // some specific data structure
class In2 { } // some specific data structure
class Out3 { } // some specific data structure
class In3 { }
internal interface IClassWithMethodsToCall
{
Out1 GetOut1(In1 inParam);
Out2 GetOut2(In2 inParam);
Out3 GetOut3(In3 inParam);
}
class ClassWithMethodsToCallImpl: IClassWithMethodsToCall
{
public Out1 GetOut1(In1 inParam) { return null; } // would have some spesific implementation
public Out2 GetOut2(In2 inParam) { return null; }
public Out3 GetOut3(In3 inParam) { return null; }
}
class ClassWithMethodsToCall: IClassWithMethodsToCall
{
private readonly ClassWithMethodsToCallImpl _impl;
public ClassWithMethodsToCall(ClassWithMethodsToCallImpl impl)
{
_impl = impl;
}
public Out1 GetOut1(In1 inParam)
{
return tryFunc(() => _impl.GetOut1(inParam));
}
public Out2 GetOut2(In2 inParam)
{
return tryFunc(() => _impl.GetOut2(inParam));
}
public Out3 GetOut3(In3 inParam)
{
return tryFunc(() => _impl.GetOut3(inParam));
}
private static T tryFunc<T>(Func<T> func)
{
try
{
return func();
}
catch (Exception exception)
{
// Do something with exception
throw;
}
}
}
Client code would only use an IClassWithMethodsToCall, and you would probably use a factory method somewhere which creates a ClassWithMethodsToCallImpl and uses it to create a ClassWithMethodsToCall and returns the ClassWithMethodsToCall as an IClassWithMethodsToCall.
Alternatively (and probably better) would be to use Aspect-oriented programming. That requires more investment and probably the use of third party libraries to support it, but it's probably the way to go in the long term.
I notice that you are using a WCF proxy. Because that uses MarshalByRefObject it may be possible for you to leverage that to implement AOP. There's some information about it in a blog here.
Related
Context:
I consume a ERP WebService exposing N methods like:
FunctionNameResponse FunctionName(FunctionNameQuery query)
I made a functional wrapper in order to:
Get rid off wrapper object FunctionNameResponse and FunctionNameQuery, that every method has.
One instance of the WebService for all the program.
Investigate and log error in the wrapper.
Investigate Slow running and Soap envelope with IClientMessageInspector
Duplicated code:
For each of the methods of the WebService I end up with around thirty lines of code with only 3 distinct words. Type response, type query, method name.
public FooResponse Foo(FooQuery query)
{
// CheckWebServiceState();
FooResponse result = null;
try
{
result =
WSClient
.Foo(query)
.response;
}
catch (Exception e)
{
// SimpleTrace();
// SoapEnvelopeInterceptorTrace();
// TimeWatch_PerformanceIEndpointBehaviorTrace();
}
return result;
}
I would like to reduce those repetition. In order to :
Make it easier to add a Method;
Avoid copy pasting programming with no need to understand what you are doing.
Easier to add specific catch and new test without the need to copy past in every method.
The following code work and exist only in the imaginary realm. It's a not functional sketch of my solution using my limited understanding.
public class Demo
{
public enum WS_Method
{
Foo,Bar,FooBar
}
public class temp
{
public Type Query { get; set; }
public Type Response { get; set; }
public WS_Method MethodName { get; set; }
}
public static IEnumerable<temp> TestFunctions =>
new List<temp>
{
new temp{Query=typeof(FooQuery), Response=typeof(FooResponse), MethodName=WS_Method.Foo },
new temp{Query=typeof(BarQuery), Response=typeof(BarResponse), MethodName=WS_Method.Bar },
new temp{Query=typeof(FooBarQuery), Response=typeof(FooBarResponse), MethodName=WS_Method.FooBar },
};
public static void Run()
{ // Exemple of consuming the method
var input = new BarQuery { Bar_Label = "user input", Bar_Ig = 42 };
BarResponse result = Execute<BarQuery, BarResponse>(input);
}
public static T2 Execute<T1,T2>(T1 param) {
//Get temp line where Query type match Param Type.
var temp = TestFunctions.Single(x => x.Query == typeof(T1));
var method = typeof(DemoWrapper).GetMethod(temp.MethodName.ToString(), new Type[] { typeof(T1) });
var wsClient = new DemoWrapper();
T2 result = default(T2);
try
{
result =
method
.Invoke(wsClient, new object[] { param })
.response;
}
catch (Exception e)
{
// SimpleTrace();
// SoapEnvelopeInterceptorTrace();
// TimeWatch_PerformanceIEndpointBehaviorTrace();
}
return result;
}
}
I know the reflection is heavy and perhaps it's not the right way to achieve this refactoring. So the question is:
How do I refactor those function?
attachment : Live demo https://dotnetfiddle.net/aUfqNp.
In this scenario:
You have a larger block of code which is mostly repeated
The only difference is a smaller unit of code that's called inside the larger block
You can refactor this by passing the smaller unit of code as a Func or Action as a parameter to the larger function.
In that case your larger function looks like this:
public TResponse GetResponse<TResponse>(Func<TResponse> responseFunction)
{
var result = default(TResponse);
try
{
result = responseFunction();
}
catch (Exception e)
{
// SimpleTrace();
// SoapEnvelopeInterceptorTrace();
// TimeWatch_PerformanceIEndpointBehaviorTrace();
}
return result;
}
The individual functions which call it look like this, without all the repeated code:
public FooResponse Foo(FooQuery query)
{
return GetResponse(() => WSClient.Foo(query));
}
Here's another approach where you keep the methods but have them all call a method that handles the duplication.
public class Demo
{
private _wsClient = new DemoWrapper();
public static void Run()
{ // Exemple of consuming the method
var input = new BarQuery { Bar_Label = "user input", Bar_Ig = 42 };
BarResponse result = Bar(input);
}
public FooResponse Foo(FooQuery foo) =>
Execute(foo, query => _wsClient.Foo(query));
public BarResponse Bar(BarQuery bar) =>
Execute(bar, query => _wsClient.Bar(query));
public FooBarResponse FooBar(FooBarQuery fooBar) =>
Execute(fooBar, query => _wsClient.FooBar(query));
private static TResponse Execute<TQuery ,TResponse>(
TQuery param, Func<TQuery, TResponse> getResponse)
{
//Get temp line where Query type match Param Type.
var result = default(TResponse);
try
{
result = getResponse(query);
}
catch (Exception e)
{
// SimpleTrace();
// SoapEnvelopeInterceptorTrace();
// TimeWatch_PerformanceIEndpointBehaviorTrace();
}
return result;
}
}
Initially I had this structure:
interface IFileBackup
{
void Backup();
}
class BackUpMechanism1 : IFileBackup
{
void Backup()
{
//Back it up
}
}
class BackUpMechanism2 : IFileBackup
{
void Backup()
{
//Back it up in another way
}
}
class Client
{
//Instantiation of both mechanisms
//
try
{
backUpMechanism1.Backup();
}
catch(Exception ex)
{
backupMechanism2.Backup();
}
}
I was told that this was not a very clean design and to redesign it using the decorator pattern. The client should not know about the two back up mechanisms but just call backup and then the first mechanism should try to back up the file and if that fails then use mechanism 2. However I don't understand how to use the decorator pattern because from my understanding it extends functionality but doesn't replace functionality - which is what I want... How do I archive that? I have tried the following:
interface IFileBackup
{
void Backup();
}
class BackupMechanism1 : IFileBackup
{
public void Backup()
{
try
{
Console.WriteLine("Trying to back up to the cloud...");
throw new Exception();
}
catch(Exception ex)
{
Console.WriteLine("Oops that failed. We need to back up locally instead...");
}
}
}
class BackupMechanism2 : IFileBackup
{
IFileBackup _fileBackup;
public BackupMechanism2(IFileBackup fileBackup)
{
_filebackup = fileBackup;
}
public void Backup()
{
//All examples I have seen does this. But doesn't make sense in my case?
_fileBackup.Backup();
Console.WriteLine("Backing up locally");
}
}
//The client does not care about how the backup is done
class Client
{
static void Main()
{
//This is not right, but not sure what I should do in the client.
BackupMechanism2 localBackup = new BackupMechanism2(new BackupMechanism1());
localBackup.Backup();
Console.Read();
}
}
So essentially what I want to achieve is to have two backup mechanisms. Have the client just say backup I don't care how. Let the first mechanism try it's backup method if that fails then try the second method. I'm trying to use the decorator pattern to extend(replace) the backup behaviour of the first mechanism if it fails. I'm struggling to come up with a design that makes sense.
A very clean approach of implementing this would be adding a composite IFileBackup taking an array of IFileBackup objects, and trying them one by one until a working solution is found:
class CompositeBackup {
private readonly IFileBackup[] chain;
public CompositeBackup(params IFileBackup[] chain) {
this.chain = chain.ToArray();
}
public void Backup() {
foreach (var backup in chain) {
try {
backup.Backup();
return;
} catch {
continue;
}
}
throw new InvalidOperationException();
}
}
Now the client simply does this:
IFileBackup backup = new CompositeBackup(
new BackupMechanism1()
, new BackupMechanism2()
);
backup.Backup();
If you later decide to add BackupMechanism3 and BackupMechanism4, the user would need to add another object to the chain of backups. The rest of the code would remain unchanged. In addition, backup mechanisms themselves would remain unaware of other mechanisms' existence, which also simplifies the code.
The decorator pattern, in this case, can be used to provide fallback implementations. You can find plenty of obvious examples in the .Net streams implementation.
So with that in mind, your code should look something like this:
class abstract BaseFileBackup
{
internal BaseFileBackup Fallback;
internal BaseFileBackup(BaseFileBackup fallback) { Fallback = fallback; }
internal BaseFileBackup() { }
internal abstract void DoBackupWork();
internal void Backup()
{
try { DoBackupWork(); }
catch { if(Fallback != null) Fallback.Backup(); else throw; }
}
}
class BackUpMechanism1 : BaseFileBackup
{
internal BackUpMechanism1 (BaseFileBackup fallback): base(fallback) {}
internal BackUpMechanism1 (): base() {}
internal void DoBackupWork()
{
//Back it up
}
}
class BackUpMechanism2 : BaseFileBackup
{
internal BackUpMechanism2 (BaseFileBackup fallback): base(fallback) {}
internal BackUpMechanism2 (): base() {}
internal void DoBackupWork()
{
//Back it up in another way
}
}
// and to call it
class Client
{
static void Main()=>
new BackupMechanism2(new BackupMechanism1()).Backup();
}
Decorator Pattern is the WRONG choice in this scenario.
The problem that you are dealing with here is
under condition x call one method
under condition y call a different method
...
This is the precondition for the Strategy Pattern, and your initial solution was quite close to that. The problem in my mind is that you are using an Exception to determine the program flow, which is a BAD thing to do: exceptions cost stack space, and they should only be thrown under EXCEPTIONAL circumstances. Whereas in your case, it is expected that a given strategy will not work
IFileBackupStrategy
{
bool Backup(File fileToBackup);
}
IFileBackupContext
{
File ForBackup { set; }
bool Backup();
}
class CloudBackUp : IFileBackupStrategy
{
private bool _success;
public bool Backup(File fileToBackup)
{
// code to do backup omitted
// it will set the value of _success to false if it was unsuccessful
return _success;
}
}
class LocalBackUp : IFileBackupStrategy
{
private bool _success;
public bool Backup(File fileToBackup)
{
// code to do backup omitted
// it will set the value of _success to false if it was unsuccessful
return _success;
}
}
public class FileBackupContext : IFileBackupContext
{
private IEnumerable<IFileBackupStrategy> _backupStrategies
public Context(IEnumerable<IFileBackupStrategy> backupStrategies)
=> _backupStrategies = backupStrategies;
public File ForBackup { set; private get; }
public bool Backup()
{
bool successFlag;
foreach(var strategy in _backupStrategies)
{
successFlag = strategy.Backup(ForBackup);
if(successFlag) break;
}
return successFlag;
}
}
In this case, all that the client needs to be aware of is the IFileBackupContext, and not the strategy employed to do the saving.
public class MyBackupClient
{
private IFileBackupContext _context;
public MyBackupClient(IFileBackupContext context) => _context = context;
void SomeMethodThatInvokesBackingUp()
{
_context.ForBackup = new File(/* */);
if(!_context.Backup())
{
Console.WriteLine("Failed to backup the file");
}
}
}
The beauty of this design is that you can add more IFileBackupStrategy implementations, register them with your DI Container and voila they are instantly available to the client without a single code change or the need for re-compilation (though that will ultimately depend upon how you are populating your DI Container)
The decorator pattern is a method of adhering to the O principle in SOLID: which is
Open for extension and closed for modification
This means that you would use the decorator pattern to decorate an existing class, one that should not be changed and yet does not exhibit the behaviour required. The clue is in the name of the pattern: Decorator adds something, it does not change anything.
The Decorator Pattern is a Structural Pattern, whereas the Strategy Pattern, and what you are looking for, is a Behavioural Pattern
This example can be extended of course to report back the strategy which was ultimately employed, and also (if required) any reasoning for why alternate strategies were not.
Edited: in response to Blindy's comment below. Here is the paradigm for the decorator pattern, which should demonstrate how it is not the correct pattern for this problem:
class Image
{
void Render() { /* */ }
}
class FramedImage : Image
{
private Image _originalImage;
public FramedImage(Image original) => _originalImage = original;
new public void Render()
{
/* code to render a frame */
_originalImage.Render();
}
}
Image originalImage = new Image();
Image framedImage = new FramedImage(originalImage);
Image toRender = originalImage;
toRender.Render() // Renders the original image
toRender = framedImage;
toRender.Render(); // Renders the original image in a frame
It should be observed that there is no need to assign each Image to the toRender variable, that is done solely to demonstrate that a decorator is a decorated.
As you can see from this example, the decorator pattern adds behaviour, and it also invokes the decorated item's behaviour.
Edited: Further to the question posed by DSF below. Here is the full listing for a console app demonstrating how to achieve this using Unity 5.8.6
The code takes advantage of the new Tuple from C# 7.0.
I've just used some random number generation to determine whether or not each strategy implementation succeeds in performing its task.
using System;
using System.Collections.Generic;
using System.IO;
using Unity;
using Unity.Injection;
namespace StrategyPattern
{
public interface IFileBackupContext
{
FileStream ForBackup { set; }
(bool success, string strategy) Backup();
}
public interface IFileBackupStrategy
{
(bool success, string name) Backup(FileStream fileToBackup);
}
internal class LocalBackUp : IFileBackupStrategy
{
private bool _success = false;
public (bool success, string name) Backup(FileStream fileToBackup)
{
// code to do backup omitted
var random = new Random(DateTime.Now.Millisecond);
_success = (random.Next() % 3) == 0;
if(_success) fileToBackup.Close();
// it will set the value of _success to false if it was unsuccessful
return (_success, "LocalBackUp");
}
}
internal class CloudBackUp : IFileBackupStrategy
{
private bool _success = false;
public (bool success, string name) Backup(FileStream fileToBackup)
{
// code to do backup omitted
var random = new Random(DateTime.Now.Millisecond);
_success = (random.Next() % 3) == 0;
if (_success) fileToBackup.Close();
// it will set the value of _success to false if it was unsuccessful
fileToBackup.Close();
return (_success, "CloudBackUp");
}
}
public class FileBackupContext : IFileBackupContext
{
private readonly IEnumerable<IFileBackupStrategy> _backupStrategies;
public FileBackupContext(IEnumerable<IFileBackupStrategy> backupStrategies)
=> _backupStrategies = backupStrategies;
public FileStream ForBackup { set; private get; }
public (bool success, string strategy) Backup()
{
foreach (var strategy in _backupStrategies)
{
var (success, name) = strategy.Backup(ForBackup);
if (success) return (true, name);
}
return (false, "");
}
}
public class MyBackupClient
{
private IFileBackupContext _context;
public MyBackupClient(IFileBackupContext context) => _context = context;
public void BackgUpMyFile()
{
_context.ForBackup = new FileStream("d:\\myfile", FileMode.OpenOrCreate);
(bool success, string strategy) = _context.Backup();
if (!success)
{
Console.WriteLine("Failed to backup the file");
return;
}
Console.WriteLine($"File backed up using [{strategy}] strategy");
}
}
public class Bootstrap
{
private readonly IUnityContainer _container;
public Bootstrap()
{
_container = new UnityContainer();
_container.RegisterType<IFileBackupContext, FileBackupContext>();
_container.RegisterType<IFileBackupStrategy, LocalBackUp>("local");
_container.RegisterType<IFileBackupStrategy, CloudBackUp>("cloud");
_container.RegisterType<MyBackupClient>();
_container.RegisterType<Func<IEnumerable<IFileBackupStrategy>>>(new InjectionFactory(c =>
new Func<IEnumerable<IFileBackupStrategy>>(() =>
new[]
{
c.Resolve<IFileBackupStrategy>("local"),
c.Resolve<IFileBackupStrategy>("cloud")
}
)));
}
public MyBackupClient GetClient() => _container.Resolve<MyBackupClient>();
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press ESC to quit ...");
Console.WriteLine("Press any other key to try again.");
Console.WriteLine();
var client = new Bootstrap().GetClient();
do
{
client.BackgUpMyFile();
} while (Console.ReadKey().Key != ConsoleKey.Escape);
}
}
}
I have my code which makes a webservice Call based on type of request.
To do that , I have following code;
public class Client
{
IRequest request;
public Client(string requestType)
{
request = new EnrolmentRequest();
if (requestType == "Enrol")
{
request.DoEnrolment();
}
else if (requestType == "ReEnrol")
{
request.DoReEnrolment();
}
else if (requestType == "DeleteEnrolment")
{
request.DeleteEnrolment();
}
else if (requestType == "UpdateEnrolment")
{
request.UpdateEnrolment();
}
}
}
So as per open close principle, I can subclass like:
Class EnrolmentRequest:IRequest
{
CallService();
}
Class ReEnrolmentRequest:IRequest
{
CallService();
}
Class UpdateEnrolmentRequest:IRequest
{
CallService();
}
Now my client class will look something like this:
public class Client
{
public Client(string requestType)
{
IRequest request;
if (requestType == "Enrol")
{
request = new EnrolmentRequest();
request.CallService();
}
else if (requestType == "ReEnrol")
{
request = new REnrolmentRequest();
request.CallService();
}
else if (requestType == "DeleteEnrolment")
{
request = new UpdateEnrolmentRequest();
request.CallService();
}
else if (requestType == "UpdateEnrolment")
{
request = new UpdateEnrolmentRequest();
request.CallService();
}
}
}
Now , I still have to use if and else , and will have to change my code if there are any new request type.
So, it's definitely, not closed to modification.
Am I missing any thing with respect to SOLID?
Can I use dependency injection, to resolve the types at Run time?
The need to write new code to handle new requirements is not going to disappear. The goal is to not have to change the old code when handling new requirements, and your class structure deals with it.
You can minimize the changes by replacing your chain of conditionals with some other mechanism of creating new instances. For example, you can build a dictionary, or use a dependency injection framework to associate a type with a string.
Here is an implementation without using DI framework:
private static readonly IDictionary<string,Func<IRequest>> ReqTypeMapper =
new Dictionary<string,Func<IRequest>> {
{"Enrol", () => new EnrolmentRequest() }
, {"ReEnrol", () => new ReEnrolmentRequest() }
, ...
};
Now the call will look like this:
Func<IRequest> maker;
if (!ReqTypeMapper.TryGetValue(requestType, out maker)) {
// Cannot find handler for type - exit
return;
}
maker().CallService();
You can't really remove the list of if-else or switch-case statements completely, unless you revert to using reflection. Somewhere in the system you will definately have some sort of dispatching (either using a hard-coded list or through reflection).
Your design however might benefit from a more message based approach, where the incomming requests are message, such as:
class DoEnrolment { /* request values */ }
class DoReenrolment { /* request values */ }
class DeleteEnrolment { /* request values */ }
class UpdateEnrolment { /* request values */ }
This allows you to create a single interface defenition for 'handlers' of such request:
interface IRequestHandler<TRequest> {
void Handle(TRequest request);
}
Your handlers will look as follows:
class DoEnrolmentHandler : IRequestHandler<DoEnrolment> {
public void Handle(DoEnrolment request) { ... }
}
class DoReenrolmentHandler : IRequestHandler<DoReenrolment> {
public void Handle(DoReenrolment request) { ... }
}
class DeleteEnrolmentHandler : IRequestHandler<DeleteEnrolment> {
public void Handle(DeleteEnrolment request) { ... }
}
Advantage of this is that applying cross-cutting concerns is a breeze, since it is very straightforward to define a generic decorator for IRequestHandler<T> that implements something like logging.
This still brings us back to the dispatching of course. Dispatching can be extracted from the client, behind its own abstraction:
interface IRequestDispatcher {
void Dispatch<TRequest>(TRequest request);
}
This allows the client to simply send the request it requires:
// Client
this.dispatcher.Dispatch(new DoEnrolment { EnrolId = id });
An implementation of the request dispatcher might look like this:
class ManualRequestDispatcher : IRequestDispatcher {
public void Dispatch<TRequest>(TRequest request) {
var handler = (IRequestHandler<TRequest>)CreateHandler(typeof(TRequest));
handler.Handle(request);
}
object CreateHandler(Type type) =>
type == typeof(DoEnrolment)? new DoEnrolmentHandler() :
type == typeof(DoReenrolment) ? new DoReenrolment() :
type == typeof(DeleteEnrolment) ? new DeleteEnrolment() :
type == typeof(UpdateEnrolment) ? new UpdateEnrolment() :
ThrowRequestUnknown(type);
object ThrowRequestUnknown(Type type) {
throw new InvalidOperationException("Unknown request " + type.Name);
}
}
If you use a DI Container however, you will be able to batch-register your request handlers with something as follows (depending on the library you use of course):
container.Register(typeof(IRequestHandler<>), assemblies);
And your dispatcher might look as follows:
class ContainerRequestDispatcher : IRequestDispatcher {
private readonly Container container;
public ContainerRequestDispatcher(Container container) {
this.container = container;
}
public void Dispatch<TRequest>(TRequest request) {
var handler = container.GetInstance<IRequestHandler<TRequest>>();
handler.Handle(request);
}
}
You can find more information about this type of design here and here.
You can add simple factory class like below:
public class ServiceFactory : Dictionary<string, Type>
{
public void Register(string typeName, Type serviceType) {
if (this.ContainsKey(typeName)) {
throw new Exception("Type registered");
}
this[typeName] = serviceType;
}
public IRequest Resolve(string typeName) {
if (!this.ContainsKey(typeName)) {
throw new Exception("Type not registered");
}
var type = this[typeName];
var service = Activator.CreateInstance(type);
return service as IRequest;
}
}
then register services in one place like:
var serviceFactory = new ServiceFactory();
serviceFactory.Register("Enrol", typeof(EnrolmentRequest));
serviceFactory.Register("ReEnrol", typeof(REnrolmentRequest));
serviceFactory.Register("DeleteEnrolment", typeof(UpdateEnrolmentRequest));
serviceFactory.Register("UpdateEnrolment", typeof(UpdateEnrolmentRequest));
and call it:
var service = serviceFactory.Resolve(requestType);
service.CallService();
also need to add proper error handling
Good question,
you can achieve your goal using one single method:
var request = (IRequest)Activator.CreateInstance("NameOfYourAssembly", requestType);
request.CallService();
Reflection will help you generating your class instance. After that you can call it without if/else.
Please refer to this link for more information about provided method: https://msdn.microsoft.com/it-it/library/3k6dfxfk(v=vs.110).aspx
Hope this can help
You can use Factory Pattern With RIP (Replace If with Polymorphism) to avoid multiple if-else.
Following code is the sample code according to your Client class :
public enum RequestType : int
{
Enrol = 1,
ReEnrol,
UpdateEnrolment
}
public interface IRequest
{
void CallService();
}
public class EnrolmentRequest : IRequest
{
public void CallService()
{
// Code for EnrolmentRequest
}
}
public class ReEnrolmentRequest : IRequest
{
public void CallService()
{
// Code for ReEnrolmentRequest
}
}
public class UpdateEnrolmentRequest : IRequest
{
public void CallService()
{
// Code for UpdateEnrolmentRequest
}
}
// Factory Class
public class FactoryChoice
{
private IDictionary<RequestType, IRequest> _choices;
public FactoryChoice()
{
_choices = new Dictionary<RequestType, IRequest>
{
{RequestType.Enrol, new EnrolmentRequest() },
{RequestType.ReEnrol, new ReEnrolmentRequest()},
{RequestType.UpdateEnrolment, new UpdateEnrolmentRequest()}
};
}
static public IRequest getChoiceObj(RequestType choice)
{
var factory = new FactoryChoice();
return factory._choices[choice];
}
}
and it will be call like :
IRequest objInvoice = FactoryChoice.getChoiceObj(RequestType.ReEnrol);
objInvoice.CallService();
Here, main things happened in the FactoryChoice class constructor. That's why someone called it smart constructor. This way you can avoid multilpe if-else or switch-case.
To know the basic of RIP you can check my slide here.
you can use autofac keyed or named service..
public enum OperationType
{
Enrol,
ReEnrol,
DeleteEnrolment,
UpdateEnrolment
}
//register types
builder.RegisterType<EnrolmentRequest>().Keyed<IRequest>(OperationType.Enrol);
builder.RegisterType<ReEnrolmentRequest>().Keyed<IRequest>(OperationType.ReEnrol);
builder.RegisterType<UpdateEnrolmentRequest>().Keyed<IRequest>(OperationType.DeleteEnrolment | OperationType.UpdateEnrolment);
// resolve by operationType enum
var request = container.ResolveKeyed<IRequest>(OperationType.Enrol);
I have a class which exposes some functionality,
and I want to ensure exceptions will be handled by a custom ErrorHandler class.
Currently I can achieve this by a try / catch statement per each method, and process the exception by the error handler there.
My question is if there is a better way / design pattern to do it.
Code:
public class BasicErrorHandler
{
public void ProcessException(Exception ex)
{
//Does error handling stuff
}
}
public class Manager
{
BasicErrorHandler _errorHandler;
public Manager()
{
_errorHandler = new BasicErrorHandler();
}
public void MethodA()
{
try
{
//Does Something
}
catch(Exception ex)
{
_errorHandler.ProcessException(ex);
}
}
public void MethodB()
{
try
{
//Does Something Else
}
catch(Exception ex)
{
_errorHandler.ProcessException(ex);
}
}
}
In keeping with DRY principles, you could just wrap your try...catch logic into into own method which takes a predicate of the actual work to do:
public class Manager
{
BasicErrorHandler _errorHandler;
public Manager()
{
_errorHandler = new BasicErrorHandler();
}
public void MethodA()
{
DoWork( () => {
// do something interesting here
});
}
public void MethodB()
{
DoWork( () => {
// do something else interesting here
});
}
private void DoWork(Action action)
{
try
{
action();
}
catch(Exception ex)
{
_errorHandler.ProcessException(ex);
}
}
}
I've crafted this quickly and without thinking too much in the implications, but if you want to avoid all the try/catch blocks, you could do something like:
public class BasicErrorHandler
{
public void ProcessException(Exception ex)
{
//Does error handling stuff
}
public void Do(Action act)
{
try
{
act();
}
catch(Exception ex)
{
ProcessException(ex);
}
}
}
And then use it like:
public class Manager
{
BasicErrorHandler _errorHandler;
public Manager()
{
_errorHandler = new BasicErrorHandler();
}
public void MethodA()
{
_errorHandler.Do(() => {
//Does Something
});
}
public void MethodB()
{
_errorHandler.Do(() => {
//Does Something Else
});
}
}
Design patterns are there to solve a problem. Which problem are you trying to solve? What is wrong with the Try Catch blocks?
Only thing I can imagine is you want to have more clean code. Some answers suggest a helper method with an action. Given the helper methods that encapsulate a delegate: Do consider the impact on your stack trace and debugging sessions using these delegates. It might make logging etc more hard to understand.
If your intend is to do separation of concern, I would say If you can't handle it, just don't catch the exception. Let the class invoking the method handle it. If you insist to have a handler in your class, I would suggest Inversion of Control. That way, your class is not in control of determining which class should handle its exceptions.
Rx .net is for You. Advanced error handling gives You the ability to highly customize Your error handling. Check out the pages about that.
For example:
var source = new Subject<int>();
var result = source.Catch<int, TimeoutException>(tx=>Observable.Return(-1));
result.Dump("Catch");
source.OnNext(1);
source.OnNext(2);
source.OnError(new ArgumentException("Fail!"));
You'll get the following output:
Catch-->1
Catch-->2
Catch failed-->Fail!
The number of retries, the handling of how much time a method can take, everything can be configured.
The following is an Aspect oriented method of soling the problem, this makes use of PostSharp to do the weaving.
[Serializable]
public class HandleExceptionsAttribute : OnExceptionAspect {
/// <summary>
/// Initializes a new instance of the <see cref="HandleExceptionsAttribute"/> class.
/// </summary>
public HandleExceptionsAttribute() {
AspectPriority = 1;
}
public override void OnException(MethodExecutionArgs args) {
//Suppress the current transaction to ensure exception is not rolled back
using (var s = new TransactionScope(TransactionScopeOption.Suppress)) {
//Log exception
using (var exceptionLogContext = new ExceptionLogContext()) {
exceptionLogContext.Set<ExceptionLogEntry>().Add(new ExceptionLogEntry(args.Exception));
exceptionLogContext.SaveChanges();
}
}
}
}
[HandleExceptions]
public class YourClass {
}
I have two classes named ROAD and PATH
public class ROAD
{
public string getData()
{
return "Marlton Road";
}
}
public class PATH
{
public string getData()
{
return "Tagore Path";
}
}
Also i have a function named FETCH() in my Static Void Main
FETCH() contains following code
public returnType FETCH(bool flag)
{
if(flag)
{
ROAD obj=new ROAD();
return obj;
}
else
{
PATH obj=new PATH();
return obj;
}
}
Now my question is what should be the return type of function FETCH().
Or is there any other way to implement this logic.
It would have to be object in this case, as PATH and ROAD have no common base type. (They also don't follow .NET naming conventions - something which should be fixed, along with your getData method, and your FETCH method. Even in sample code, it's worth trying to make your names follow the normal conventions).
Consider making the two classes implement an interface or give them a common base class. That common type could then be the return type of the method. It looks like you could probably have an interface with your getData method in, for example. Hopefully in your real classes it could have a more meaningful name - something to do with both paths and roads.
I suggest you create an interface that both PATH and ROAD implement (e.g. IGetData) then have both classes implement it, and have FETCH return an IGetData.
Object, and then you cast to ROAD or PATH. Or, if they share a common base class, return that. See also.
But you probably don't want to do this. ROAD and PATH should each have their own static factory method:
class ROAD {
static ROAD newRoad() { return new ROAD(); }
}
class PATH {
static PATH newPath() { return new PATH(); }
}
Or some other, better pattern, depending on why you're doing it this way.
using interface would be the best way:
public interface IData
{
string getData();
}
public class ROAD : IData
{
public string getData()
{
return "Marlton Road";
}
}
public class PATH : IData
{
public string getData()
{
return "Tagore Path";
}
}
public IData FETCH(bool flag)
{
if (flag)
{
ROAD obj = new ROAD();
return obj;
}
else
{
PATH obj = new PATH();
return obj;
}
}
How about this:
interface IWithData
{
string GetData();
}
class Path: IWithData
{
public string GetData()
{
return "Tagore Path";
}
}
class Road: IWithData
{
public string GetData()
{
return "Marlton Road";
}
}
class SomeOtherClass
{
// ...
public IWithData FETCH(bool flag)
{
if(flag)
{
Road obj=new Road();
return obj;
}
else
{
Path obj=new Path();
return obj;
}
}
// ...
}
It's object. If you want it to be something else, you just have to have those classes share a common base or implement a common interface. For example:
public class Road : IPavedSurface
{
// members
}
public class Path : IPavedSurface
{
// members
}
// then
public IPavedSurface Fetch(bool flag)
{