I have implemented a generic method for calling function in my web service methods and catching exceptions. The idea is to centralize the exception handling and log why the exception occured:
public class WebServiceHandler
{
public T Execute<T>(Func<T> body)
{
//wrap everything in common try/catch
try
{
return body();
}
catch (SoapException)
{
//rethrow any pre-generated SOAP faults
throw;
}
catch (Exception ex)
{
Logger.AddTextToLog(Logger.LogLevel.Error, "An error occured");
var innerExceptionMessage = ex.InnerException != null ? ex.InnerException.Message : "";
throw GenerateSoapException(
ex.Message,
innerExceptionMessage,
SoapException.ServerFaultCode);
}
}
}
I'm using the method like this in my web service methods:
[WebMethod]
GetXXX(string param1, string param2)
{
var request = new GetXXXRequest(param1, param2);
return _webServiceHandler.Execute(() => _controller.GetXXX(request));
}
[WebMethod]
GetYYY(string param1)
{
var request = new GetYYYRequest(param1);
return _webServiceHandler.Execute(() => _controller.GetYYY(request));
}
In case of exceptions I would like to log the parameter names and values used as input to the controller.GetXXX(request) and controller.GetYYY(request) methods in the Execute method.
How can I achieve this?
Or is there a better way to achieve the same goal?
I did not tried with expressions but I have a solution for delegates;
public static List<object> GetMethodParameterValues(Delegate method)
{
var target = method.Target;
if (target == null) return null;
var fields = target.GetType().GetFields();
var valueList = fields.Select(field => field.GetValue(target)).ToList();
return valueList;
}
First of all you can't query the runtime for the that information magically, implicitly.
It is true that you can implicitly learn the complete identity of the currently executing method, its caller, its caller's caller and all of the stacktrace (except for the particular generic arguments in case of generic methods) by instantiating the StackTrace class or by calling the MethodBase.GetCurrentMethod() method.
It is also true that the resulting MethodBase instances hold information about the methods' parameters and so, you might be able to learn the names of the parameters, but that's where it all ends. If a mechanism allowing you to implicitly probe for parameter or local variable values would've been invented then everything would be a lot slower.
What you can do, is help yourself, a bit, by means of the Expression<Lambda> class and its entourage. It's gonna be a bit slow, but you get to choose whether you want reviewable and easy to manage code, or misteriously hard to manage and very very fast code.
Expression<Lambda> is how LINQ manages to not do a full table scan of database tables but rather understand what you did with your query and translate that (at runtime) into SQL or whatever other language you might imagine (depending on the actual LINQ provider).
First of all, I would suggest splitting concerns into 2 categories:
Retrieving names and values (as implicitly as possible)
Using names and values (wherever you want to)
To make that happen you need to think about an entity which can hold the results of point 1. In my suggestion to you that would be a kind of Dictionary<string, object> but you can do whatever suits you best.
My suggestion can be used like so:
public void SomeMethod(string x, int y) {
IDictionary<string, object> paramValues = Helper.TapInto(
() => x,
() => y
);
// paramValues["x"] an paramValues["y"] will hold the values of x and y
}
So, on to the coding bit. You could write a Helper class like so:
public static class Helper {
}
In that Helper class you could invent a static method ( I called mine TapInto maybe that's not the best name for it ) which receives a primitive array of Expression<Func<object>> instances. It does that with a params modifier so that you can easily pass implicit lambdas to it. As a return it gives you a hashtable from string to object representing the "decompiled" variable names and their associated values.
In my case, I also created a private overload of that same method which is actually an "extension" method, to make the code clearer.
public static class Helper {
// ... an overload of the TapInto method is about to appear right here
public static IDictionary<string, object> TapInto(params Expression<Func<object>>[] parameterTouchers) {
var result = new Dictionary<string, object>();
foreach (var toucher in parameterTouchers) {
string name;
object value;
toucher.TapInto(out name, out value);
result[name] = value;
}
return result;
}
So all the public method does is iterate through the list and accumulate the yielded results into the dictionary.
Next let's look at the real magic, which happens in the toucher.TapInto(out name, out value) call:
public static class Helper {
private static void TapInto(this Expression<Func<object>> #this, out string name, out object value) {
Expression expression = #this.Body;
if (expression is UnaryExpression)
expression = (expression as UnaryExpression).Operand;
name = (expression as MemberExpression).Member.Name;
Func<object> compiledLambda = #this.Compile();
value = compiledLambda();
}
// ... public helper method right here
}
What we're doing here is "we're looking inside" the lambda with a magnifying glass.
Because we're gonna use stuff other than object variables it's imminent to observe an implicit conversion like
.. int someParameter ..
object obj = someParameter;
which is only implicit in the actual C# code, but is actually compiled as an explicit conversion:
object obj = (object)someParameter;
But you might have a plain object parameter, like object anotherParam, in which case there would be no conversion at all.
That is why, upon observing the expression's intricate details, I presume I might find a conversion ( represented by the UnaryExpression class ) or not.
Actually it's like saying: In this particular case, my contract to the calling code is that it may send me only stuff which falls into these 2 categories:
Immediate object variable reference: () => someObjectVariable
Variable reference with a conversion: () => (object)x
The contract also accidentally states that the "conversion" bit can be replaced by a UnaryExpression, for instance: () => !someBool.
It also states that you cannot do something like:
() => 123
or () => a + b + c + 100
or anything else in those directions
So, to wrap it up:
You could write your nice little helper
You could use it wherever you want to use it to produce maps between param names and their values although it's not 100% implicit, but at least it won't compile if you rename a parameter without complete refactoring or it will let you rename the parameter references if you choose to rename the parameters using refactoring
(it also works on fields, local variables, etc)
Pass your dictionaries in between parts of your code that are interested in them and use them accordingly !
You can use another parameter to the Execute method to get callback from function.
An Action or your result type. In this case string for example:
public T Execute<T>(Func<T> body, Action<string> callback)
{
//wrap everything in common try/catch
try
{
//do stuff
callback("results are...");
}
You can also use a delegate:
public void CallbackDelegate( string str );
public T Execute<T>(Func<T> body, CallbackDelegate callback)
{
//wrap everything in common try/catch
try
{
//do stuff
callback("results are...");
}
Maybe something like this:
sealed class Param
{
public string Name
{
get;
private set;
}
public object Value
{
get;
private set;
}
public Param(string name, object value)
{
Name = name;
Value = value;
}
}
public T Execute<T>(Func<T> body, params Param[] parameters)
{
//wrap everything in common try/catch
try
{
return body();
}
catch (SoapException)
{
//rethrow any pre-generated SOAP faults
throw;
}
catch (Exception ex)
{
Logger.AddTextToLog(Logger.LogLevel.Error, "An error occured");
foreach (var parameter in parameters)
{
Logger.AddTextToLog(
Logger.LogLevel.Error,
string.Format(
"{0} : {1}",
parameter.Name,
parameter.Value ?? "null"));
}
var innerExceptionMessage = ex.InnerException != null ? ex.InnerException.Message : "";
throw GenerateSoapException(
ex.Message,
innerExceptionMessage,
SoapException.ServerFaultCode);
}
}
And then you call:
[WebMethod]
GetXXX(string param1, string param2)
{
var request = new GetXXXRequest(param1, param2);
return _webServiceHandler.Execute(() => _controller.GetXXX(request)
new Parameter("param1", param1),
new Parameter("param2", param2));
}
What I ended up doing was to add the request class as parameter to the Execute method like this:
public T Execute<T, TU>(Func<T> body, TU parameterClass) where TU : class
{
//wrap everything in common try/catch
try
{
return body();
}
catch (SoapException)
{
//rethrow any pre-generated SOAP faults
throw;
}
catch (Exception ex)
{
var serializedObject = ParameterUtil.GetPropertyNamesAndValues(parameterClass);
Logger.AddTextToLog(Logger.LogLevel.Error, string.Format("An error occured when calling braArkiv Web Services. Web service method arguments: {0}", serializedObject), ex);
var innerExceptionMessage = ex.InnerException != null ? ex.InnerException.Message : "";
throw GenerateSoapException(
ex.Message,
innerExceptionMessage,
SoapException.ServerFaultCode);
}
}
public static class ParameterUtil
{
public static string GetPropertyNamesAndValues<T>(T o) where T : class
{
using (var stringWriter = new StringWriter())
{
var xmlSerializer = new XmlSerializer(o.GetType());
xmlSerializer.Serialize(stringWriter, o);
stringWriter.Close();
return stringWriter.ToString();
}
}
}
Usage:
[WebMethod]
GetXXX(string param1, string param2)
{
var request = new GetXXXRequest(param1, param2);
return _webServiceHandler.Execute(() => _controller.GetXXX(request), request);
}
When an exception occurs I just serialize the parameterClass parameter containing the web service method parameters and add the string to my log.
Thank you all for the constructive input to my question!
Related
Suppose I have the following WCF code:
try
{
ServiceClient proxy = new ServiceClient();
proxy.ClientCredentials.UserName.UserName = "user";
proxy.ClientCredentials.UserName.Password = "password";
proxy.GetData(2);
if (proxy.State = CommunicationState.Opened)
{
proxy.GetData("data");
}
proxy.Close();
}
catch (FaultException ex)
{
// handle the exception
}
And since I notice that the try...catch and other logic is repetitive, not to mention that setting up a WCF call is expensive, I want to send many "methods and parameters" to this function.
In essence pass GetData(2) and GetData("data") as a method array, and have the results return either asynchronously or synchronously.
How would I accomplish this?
I suppose I could have two 'ref' objects to handle the results[] and a shared lock to the results[]. However I'm not sure how to pass "methods with parameters" as a parameter to another function.
Perhaps another way of looking at this might be an array of function pointers, to the same function with different params.
Can anyone nudge me into the right way of doing this?
More info:
I am asking this question so I can optimize this approach to handling WCF exceptions and retries but so I don't have to always open/close the client after each call.
Use delegates and pass them in a list.
The C# Func<T> delegate is used when a return value is needed.
List<Func<Data>> funcList = new List<Func<Data>>();
funcList.Add( () => GetData(2) );
// You can use any condition as you otherwise would to add to the list.
if (proxy.State = CommunicationState.Opened)
{
funcList.Add( () => GetData("data") );
}
List<Data> ProcessFuncs(List<Func<Data>> funcDatas)
{
List<Data> returnList = new List<Data>();
foreach(var func in funcDatas)
{
returnList.Add(func());
}
}
( as long as the return types are identical, this will work )
This is just an example of course; if your methods don't return anything, you can use the C# Action delegate, which just executes an action and doesn't return any value.
List<Action> actionList = new List<Action>();
actionList.Add( () => ProcessData("data")); // ProcessData is a void with no return type
actionList.Add( () => ProcessData(2));
public void ProcessActions(List<Action> actions)
{
foreach(var action in actions)
{
action();
}
}
In response to some comments:
This code compiles and is all equivalent:
class Program
{
public static string GetData(string item) { return item; }
public static string GetData(int item) { return item.ToString(); }
static void Main(string[] args)
{
string someLocalVar = "what is it?";
int someLocalValueType = 3;
Func<string> test = () =>
{
return GetData(someLocalVar);
};
Func<string> test2 = () => GetData(someLocalValueType);
someLocalValueType = 5;
List<Func<string>> testList = new List<Func<string>>();
testList.Add(() => GetData(someLocalVar));
testList.Add(() => GetData(2));
testList.Add(test);
testList.Add(test2);
someLocalVar = "something else";
foreach(var func in testList)
{
Console.WriteLine(func());
}
Console.ReadKey();
}
}
Result is:
I wouldn't use delegates here because then you are constrained by types and to solve that it becomes horrible and over-complicated. I would just have a callback that gives you free reign over the ServiceClient once it has been set up. I think this is a pattern that has a name but I don't know.
interface IProxyActionCallback
{
void DoProxyStuff(ServiceClient proxy);
}
void MyMethod(IProxyActionCallback callback)
{
try
{
ServiceClient proxy = new ServiceClient();
proxy.ClientCredentials.UserName.UserName = "user";
proxy.ClientCredentials.UserName.Password = "password";
callback.DoProxyStuff(proxy);
proxy.Close();
}
catch (FaultException ex)
{
// handle the exception
}
}
Then you call the method like:
MyMethod(new DoSpecificStuff());
Where DoSpecificStuff is a class that implements the interface and allows you to do specific calls with the proxy:
class DoSpecificStuff : IProxyActionCallback
{
public void DoProxyStuff(ServiceClient proxy)
{
proxy.GetData(2);
if (proxy.State = CommunicationState.Opened)
{
proxy.GetData("data");
}
}
}
So you'd have tons of classes that implement the interface, and they all "share" the same try-catch boiler-plate proxy stuff which is in one place.
Bellow is an example of how to make a collection of delegates and their arguments then invoke them later on without knowing the methods definition. As far as I know if you want to invoke methods with different definitions in a single general call you have to do something like this.
List<Tuple<delegate, object[]>> delegates = new List<Tuple<delegate, object[]>>();
delegates.Add(new Tuple<delegate, object[]>(new Func<Arg1Type, Arg2Type, ReturnType>(MyFunctionName), new object[] { arg1, arg2 });
foreach (Tuple<delegate, object[]> d in delegates)
{
d.Item1.DynamicInvoke(d.Item2);
}
You could use C# delegates:
A delegate is a type that represents references to methods with a
particular parameter list and return type. When you instantiate a
delegate, you can associate its instance with any method with a
compatible signature and return type. You can invoke (or call) the
method through the delegate instance. Delegates are used to pass
methods as arguments to other methods. Event handlers are nothing more
than methods that are invoked through delegates. You create a custom
method, and a class such as a windows control can call your method
when a certain event occurs. The following example shows a delegate
declaration:
More on this:
http://msdn.microsoft.com/en-us/library/ms173171.aspx
You can pass functions with parameters this way:
public void strategy<R, T1, T2>(Func<R, T1, T2> f);
public bool predicate(string a, string b);
strategy<bool, string, string>(predicate);
The first line declares the function strategy() accepting a function f;
That function return the type R and takes two parameters of type T1 and T2.
The second line defines a function that returns a bool and accepts two string.
The third line invokes the strategy passing it the predicate as a parameter.
Not sure to understand what you're trying to achieve, but basically if your service exposes a GetData(int) method and a GetData(string) method as well as an async proxy, you should call both asynchronously using something like:
var getData = proxy.GetDataAsync(2);
var getData2 = proxy.GetDataAsync("data");
await Task.WhenAll(getData, getData2);
// Gets the result using getData.Result...etc.
Tried searching online for this but no luck so far
Basically I allow the user create an expression of choices such as
TargetHealthLessThen20
TargetAboutToUsePotion
These are stored against an enum and then stored in database as a string expression such as
"TargetHealthLessThen20 || TargetAboutToUsePotion"
now I have methods for each enum to check its conditon i.e
public bool IsTargetHealthLessThen20(Target target)
{
// do login
}
public bool IsTargetAboutToUsePotion(Target target)
{
// do login
}
I want to be able to write an If statement that was dynamic to call these methods and put in the conditons such as
if("IsTargetHealthLessThen20(target) || IsTargetAboutToUsePotion(target)")
{
// Perform Action
}
Any ideas on best way of going about this?
While I wouldn't necessarily recommend the following due to performance reasons, it will do what you want.
If you are always applying your target and only your target, you can predefine a class of evaluative methods and then pass in a list of string method names to evaluate against those methods.
void Main()
{
var inputs = new List<string>();
inputs.Add("MethodA");
inputs.Add("MethodB");
var results = Evaluate(inputs, "target");
Console.WriteLine(results);
}
public bool Evaluate(List<string> predicates, string target)
{
var methods = new Methods();
var tempResult = false;
foreach (var pred in predicates)
{
var method = methods.GetType().GetMethod(pred);
if (method == null)
throw new InvalidOperationException(
string.Format("Unknown method {0}.", pred));
tempResult = (bool)typeof(Methods).GetMethod(pred).Invoke(methods, new [] {target});
if (!tempResult) break;
continue;
}
return tempResult;
}
public class Methods
{
public bool MethodA(string target)
{
return target == "target";
}
public bool MethodB(string target)
{
return target == "not a target";
}
}
This particular Evaluate function will evaluate AND conditions. You would need to change your evaluative logic for OR conditions. You could in theory inspect your strings and call a different method depending on the operators in the strings.
EDIT
A second option that would avoid reflection would be to create a Dictionary that maps your string names for your methods to the methods themselves. This would allow you to achieve the same result without reflection, although you would have to keep your dictionary in sync. On the flip side, you gain and additional compile-time check without the reflection overhead.
private static readonly Methods _methodsInstance = new Methods();
private static Dictionary<string, Func<string, bool>> _methods = new Dictionary<string, Func<string, bool>>()
{
{ "MethodA", _methodsInstance.MethodA },
{ "MethodB", _methodsInstance.MethodB },
};
public bool Evaluate(List<string> predicates, string target)
{
var tempResult = false;
foreach (var pred in predicates)
{
tempResult = _methods[pred](target);
if (!tempResult) break;
continue;
}
return tempResult;
}
I think it's diffcult. Because you don't know the target parameter value. if you know the parameter value, you can use the reflect invoke the method by expression string.
I think I have just the answer you're looking for, because I needed the nearly exact same thing in the past:
What you have there is C# code, so you need to treat it like what it is :)
Create an interface like
interface ICondition { bool Evaluate(); }
Now use the text you have there to compile it into a class.
Like this:
using YourProgramNamespace;
class myCondition : ICondition
{
bool Evaluate() { return {0} ; }
}
To pass more parameters just change the interface to allow for the matching parameters.
If you don't want multiple interfaces just make it like this:
using YourProgramNamespace;
class myCondition : ICondition
{
bool Evaluate(params object[] parameters) { return {0} ; }
}
In your text you then just write it like this:
TargetHasLessThan20Hp((TargetType)parameters[0])
Where you replace the {0} with the condition text you already have.
Use the C# compiler to compile the code.
http://msdn.microsoft.com/de-de/library/microsoft.csharp.csharpcodeprovider%28v=vs.110%29.aspx
There are more than enough tutorials on how to use it and it's usage is not that hard.
When you have compiled the class into a Dll load it and find the type with reflection, this is also not hard and there are tons of tutorials out there. Just use yourAssembly.GetTypes() and go from there
Use Activator.CreateInstance to instantiate the type you have
Then just call the evaluate function and it will return true or false.
For better performance don't compile each time until the condition text actually changes.
Need more info? Just ask and I'll edit my answer or post it in the comments.
Right now we have a set of so called 'services' - classes, that have methods with common signature: their result type have a property T? Error, where T is enum.
And we have a separate enum for each method with a set of values defined for specific method.
This works rather good as long as the final place where we use these services' methods from is controllers' actions — these errors are returned to client, where they are handled by javascript.
But sometime we want to compose some methods of calls of other services' methods, and it is the place where I seem to have a problem.
Let's say we have service's method A(), that has error of type AError. And this A() method calls internally method B() that has an error of type BError.
First of all, we have to map possible BError to AError.
And also it is possible to forget to inspect B's error, and its presence will remain unobserved.
Of cource I know that it is common to use exceptions to indicate that a method has failed.
Right now all controllers have a filter that intercepts unhandled exceptions and returns an answer with just single property Error with value 'InternalServerError'.
But if we start to use exceptions we will loose one feature that I consider important: now a possible set of method's errors is explicitly specified in its signature, and this will be lost in case of we use exceptions.
I know that there is a tag in xml-documentation to list exception types, but it is only documentation, it is not checked by a compiler.
Also I do not understand how to use exceptions on our code:
Let's say we have some method that first checks order's status. Right now it returns 'InvalidOrderStatus' error if order's status is invalid for current action.
If we use exceptions, we can create an exception InvalidOrderStatusException, but how can we know that code that we call internally throws it?
We can also create a mnemonic rule: method A should have error type AError, and inside it should throw some generic exception (let's say, ErrorException<>), parametrized by this AError. And we can intercept this generic exception ErrorException<AError> in all A's calls and observe its error code. But this will not be checked by a compiler: Method A can throw any other exception, or ErrorException<>, but parametrized by some other error code.
So my question is: what is the best way to a) always know what kind of exceptions method can throw and what kind of errors it can return, and b) not be able to forget to observe method's result error?
How about exchanging enum AError with something like this:
class ErrorHolder<T> // T would be AError, BError
{
T ErrorCode {get;}
object[] InnerErrors {get;}
// other payload could go here like inner exceptions etc.
}
Thus you have the enumerated error codes which can be somehow checked plus you can add whatever payload you need.
Create some base exception with desired behaviuor, provide base mechanizm for it's handling, processing and conversion to a result that's being sent to javascript. It doesn't mean that you need to know a list of all possbile exceptions of your method (probaly such list will always be a lie because of possbile non-business exceptions). So derived exceptions can be just a substitutions for error codes, containing specific messages and other data (error code :) ). As you say - "a possible set of method's errors is explicitly specified in its signature" imho it's not an important feature. You should be "object oriented" think of general exception handling (at controller method code level like HandleError(ExecuteService()) or at action filter level). Also, you error codes can be appear not an exceptions but some "execution results" with success or fail status, it's not an exceptional behaviour like "entity not found" but an expected result from service. In this case I use the following code
public class ExecutionResult
{
public ExecutionResult() : this(null)
{
}
public ExecutionResult(ExecutionResult result)
{
if (result != null)
{
Success = result.Success;
Errors = new List<ErrorInfo>(result.Errors);
}
else
{
Errors = new List<ErrorInfo>();
}
}
private bool? _success;
public bool Success
{
get { return _success ?? Errors.Count == 0; }
set { _success = value; }
}
public IList<ErrorInfo> Errors { get; private set; }
}
/*T is for result (any business object)*/
public class ExecutionResult<T> : ExecutionResult
{
public ExecutionResult() : this(null)
{
}
public ExecutionResult(T result) : this(null)
{
Value = result;
}
public ExecutionResult(ExecutionResult result)
: base(result)
{
var r = result as ExecutionResult<T>;
if (r != null)
{
Value = r.Value;
}
}
public T Value { get; set; }
}
So my question is: what is the best way to a) always know what kind of
exceptions method can throw and what kind of errors it can return, and
b) not be able to forget to observe method's result error?
To address "a":
It's hard to do this at compile time. But you can do it via reflection at runtime. See the static enumValues field in the ErrorHandlerFor<T> class.
To address "b", you could do it like this:
In brief: instead of a switch after the call, you prepare error handlers (formerly in the case parts) as lambdas and put all of them in a ErrorHandlerFor<T> class and pass this to the function. This adds the additional benefit of giving feedback to the function whether to continue or abort.
You can also think of this like this:
Assume you want to give some work to a fellow. This work can fail in several ways.
Traditionally you gave the fellow the work and waited till it was finished, maybe with errors. You then handled the errors if necessary.
Now you give the fellow also some "phone numbers" to call when certain errors arise. The answer to the call may even guide the fellow if the work can be continued or needs to be aborted.
enum AError
{
AError1,
AError2,
AError3,
AError4,
AError5,
}
delegate bool SingleErrorHandlerDelegate<T>(T error, object someOtherPayload);
interface IHandle<T>
{
bool Handle(T error, object someOtherPayload); // return true if handled;
}
class ErrorHandlerFor<T> : IHandle<T>
{
private Dictionary<T, SingleErrorHandlerDelegate<T>> handlers;
private static T[] enumValues = Enum.GetValues(typeof(T)).Cast<T>().ToArray();
public ErrorHandlerFor(IEnumerable<KeyValuePair<IEnumerable<T>, SingleErrorHandlerDelegate<T>>> handlers)
: this(handlers.SelectMany(h => h.Key.Select(key => new KeyValuePair<T, SingleErrorHandlerDelegate<T>>(key, h.Value))))
{
}
public ErrorHandlerFor(IEnumerable<KeyValuePair<IEnumerable<T>, SingleErrorHandlerDelegate<T>>> handlers, SingleErrorHandlerDelegate<T> fallbackHandler)
: this(handlers.SelectMany(h => h.Key.Select(key => new KeyValuePair<T, SingleErrorHandlerDelegate<T>>(key, h.Value))), fallbackHandler)
{
}
public ErrorHandlerFor(IEnumerable<KeyValuePair<T, SingleErrorHandlerDelegate<T>>> handlers)
{
this.handlers = new Dictionary<T, SingleErrorHandlerDelegate<T>>();
foreach (var handler in handlers)
{
Debug.Assert(handler.Value != null);
this.handlers.Add(handler.Key, handler.Value);
}
checkHandlers();
}
public ErrorHandlerFor(IEnumerable<KeyValuePair<T, SingleErrorHandlerDelegate<T>>> handlers, SingleErrorHandlerDelegate<T> fallbackHandler)
{
this.handlers = new Dictionary<T, SingleErrorHandlerDelegate<T>>();
foreach (var handler in handlers)
{
Debug.Assert(handler.Value != null);
this.handlers.Add(handler.Key, handler.Value);
}
foreach (var enumValue in enumValues)
{
if (this.handlers.ContainsKey(enumValue) == false)
{
this.handlers.Add(enumValue, fallbackHandler);
}
}
checkHandlers();
}
private void checkHandlers()
{
foreach (var enumValue in enumValues)
{
Debug.Assert(handlers.ContainsKey(enumValue));
}
}
public bool Handle(T error, object someOtherPayload)
{
return handlers[error](error: error, someOtherPayload: someOtherPayload);
}
}
class Test
{
public static void test()
{
var handler = new ErrorHandlerFor<AError>(
new[]{
new KeyValuePair<IEnumerable<AError>, SingleErrorHandlerDelegate<AError>>(
new []{AError.AError1, AError.AError2, AError.AError4,},
(AError error, object payload) => { Console.WriteLine(#"handled error 1, 2 or 4!"); return true;}
),
new KeyValuePair<IEnumerable<AError>, SingleErrorHandlerDelegate<AError>>(
new []{AError.AError3, AError.AError5,},
(AError error, object payload) => { Console.WriteLine(#"could not handle error 3 or 5!"); return false;}
),
}
);
var result = Services.foo(handler);
var incompleteHandlerButWithFallbackThatWillPassTheTest = new ErrorHandlerFor<AError>(
new[]{
new KeyValuePair<IEnumerable<AError>, SingleErrorHandlerDelegate<AError>>(
new []{AError.AError1, AError.AError2, AError.AError4,},
(AError error, object payload) => { Console.WriteLine(#"handled error 1, 2 or 4!"); return true;}
),
new KeyValuePair<IEnumerable<AError>, SingleErrorHandlerDelegate<AError>>(
new []{AError.AError5},
(AError error, object payload) => { Console.WriteLine(#"could not handle error 3 or 5!"); return false;}
),
}
// AError.AError3 is not handled! => will go in fallback
, (AError error, object payload) => { Console.WriteLine(#"could not handle error in fallback!"); return false; }
);
var result2 = Services.foo(incompleteHandlerButWithFallbackThatWillPassTheTest);
var incompleteHandlerThatWillBeDetectedUponInstantiation = new ErrorHandlerFor<AError>(
new[]{
new KeyValuePair<IEnumerable<AError>, SingleErrorHandlerDelegate<AError>>(
new []{AError.AError1, AError.AError2, AError.AError4,},
(AError error, object payload) => { Console.WriteLine(#"handled error 1, 2 or 4!"); return true;}
),
new KeyValuePair<IEnumerable<AError>, SingleErrorHandlerDelegate<AError>>(
new []{AError.AError3},
(AError error, object payload) => { Console.WriteLine(#"could not handle error 3 or 5!"); return false;}
),
} // AError.AError5 is not handled! => will trigger the assertion!
);
}
}
class Services
{
public static Result foo(IHandle<AError> errorHandler)
{
Debug.Assert(errorHandler != null);
// raise error...
var myError = AError.AError1;
var handled = errorHandler.Handle(error: myError, someOtherPayload: "hello");
if (!handled)
return new Result();
// maybe proceed
var myOtherError = AError.AError3;
errorHandler.Handle(error: myOtherError, someOtherPayload: 42); //we'll return anyway in this case...
return new Result();
}
public class Result
{
}
}
There are a few different common patterns for returning the result of a function call in public APIs. It is not obvious which is the best approach. Is there a general consensus on a best practice, or, at least convincing reasons why one pattern is better the others?
Update By public API, I mean the public members that are exposed to dependent assemblies. I am not referring exclusively to an API that is exposed publicly as a web service. We can make the assumption that clients are using .NET.
I wrote a sample class below to illustrate the different patterns for returning values, and I have annotated them expressing my concerns for each one.
This is a bit of a long question, but I'm sure I'm not the only person to have considered this and hopefully this question will be interesting to others.
public class PublicApi<T> // I am using the class constraint on T, because
where T: class // I already understand that using out parameters
{ // on ValueTypes is discouraged (http://msdn.microsoft.com/en-us/library/ms182131.aspx)
private readonly Func<object, bool> _validate;
private readonly Func<object, T> _getMethod;
public PublicApi(Func<object,bool> validate, Func<object,T> getMethod)
{
if(validate== null)
{
throw new ArgumentNullException("validate");
}
if(getMethod== null)
{
throw new ArgumentNullException("getMethod");
}
_validate = validate;
_getMethod = getMethod;
}
// This is the most intuitive signature, but it is unclear
// if the function worked as intended, so the caller has to
// validate that the function worked, which can complicates
// the client's code, and possibly cause code repetition if
// the validation occurs from within the API's method call.
// It also may be unclear to the client whether or not this
// method will cause exceptions.
public T Get(object argument)
{
if(_validate(argument))
{
return _getMethod(argument);
}
throw new InvalidOperationException("Invalid argument.");
}
// This fixes some of the problems in the previous method, but
// introduces an out parameter, which can be controversial.
// It also seems to imply that the method will not every throw
// an exception, and I'm not certain in what conditions that
// implication is a good idea.
public bool TryGet(object argument, out T entity)
{
if(_validate(argument))
{
entity = _getMethod(argument);
return true;
}
entity = null;
return false;
}
// This is like the last one, but introduces a second out parameter to make
// any potential exceptions explicit.
public bool TryGet(object argument, out T entity, out Exception exception)
{
try
{
if (_validate(argument))
{
entity = _getMethod(argument);
exception = null;
return true;
}
entity = null;
exception = null; // It doesn't seem appropriate to throw an exception here
return false;
}
catch(Exception ex)
{
entity = null;
exception = ex;
return false;
}
}
// The idea here is the same as the "bool TryGet(object argument, out T entity)"
// method, but because of the Tuple class does not rely on an out parameter.
public Tuple<T,bool> GetTuple(object argument)
{
//equivalent to:
T entity;
bool success = this.TryGet(argument, out entity);
return Tuple.Create(entity, success);
}
// The same as the last but with an explicit exception
public Tuple<T,bool,Exception> GetTupleWithException(object argument)
{
//equivalent to:
T entity;
Exception exception;
bool success = this.TryGet(argument, out entity, out exception);
return Tuple.Create(entity, success, exception);
}
// A pattern I end up using is to have a generic result class
// My concern is that this may be "over-engineering" a simple
// method call. I put the interface and sample implementation below
public IResult<T> GetResult(object argument)
{
//equivalent to:
var tuple = this.GetTupleWithException(argument);
return new ApiResult<T>(tuple.Item1, tuple.Item2, tuple.Item3);
}
}
// the result interface
public interface IResult<T>
{
bool Success { get; }
T ReturnValue { get; }
Exception Exception { get; }
}
// a sample result implementation
public class ApiResult<T> : IResult<T>
{
private readonly bool _success;
private readonly T _returnValue;
private readonly Exception _exception;
public ApiResult(T returnValue, bool success, Exception exception)
{
_returnValue = returnValue;
_success = success;
_exception = exception;
}
public bool Success
{
get { return _success; }
}
public T ReturnValue
{
get { return _returnValue; }
}
public Exception Exception
{
get { return _exception; }
}
}
Get - use this if validation failing is unexpected or if it's feasible for callers to validate the argument themselves before calling the method.
TryGet - use this if validation failing is expected. The TryXXX pattern can be assumed to be familiar due it's common use in the .NET Framework (e.g., Int32.TryParse or Dictonary<TKey, TValue>.TryGetValue).
TryGet with out Exception - an exception likely indicates a bug in the code passed as delegates to the class, because if the argument was invalid then _validate would return false instead of throwing an exception and _getMethod would not be called.
GetTuple, GetTupleWithException - never seen these before. I wouldn't recommend them, because a Tuple isn't self-explaining and thus not a good choice for a public interface.
GetResult - use this if _validate needs to return more information than a simple bool. I wouldn't use it to wrap exceptions (see: TryGet with out Exception).
If by "public API" you mean an API by will be consumed by applications outside of your control and those client apps will written in a variety of languages/platforms I would suggest returning very basic types (e.g. strings, integers, decimals) and use something like JSON for more complex types.
I don't think you can expose a generic class in a public API since you don't know if the client will support generics.
Pattern-wise I would lean towards a REST-like approach rather than SOAP. Martin Fowler has a good article high level article on what this means: http://martinfowler.com/articles/richardsonMaturityModel.html
Things to consider, before answer:
1- There is a special situation about DOTNet programming languages & Java, due that you can easily retrieve objects, instead of only primitive types. Example: so a "plain C" A.P.I. may differ to a C# A.P.I.
2- If there is an error in you A.P.I., while retriving a data, how to handle, without interrumpting you application.
Answer:
A pattern, I have seen in several libraries, its a function, that its main result its an integer, in which 0 means "success", and another integer value means an specific error code.
The function may have several arguments, mostly read-only or input parameters, and a single reference or out parameter that maybe a primitive type a reference to an object, that maybe changed, or a pointer to an object or data structure.
In case of exceptions, some developers, may catch them and generate an specific error code.
public static class MyClass
{
// not recomended:
int static GetParams(ref thisObject, object Param1, object Params, object Param99)
{
const int ERROR_NONE = 0;
try
{
...
}
catch (System.DivideByZeroException dbz)
{
ERROR_NONE = ...;
return ERROR_NONE;
}
catch (AnotherException dbz)
{
ERROR_NONE = ...;
return ERROR_NONE;
}
return ERROR_NONE;
} // method
// recomended:
int static Get(ref thisObject, object ParamsGroup)
{
const int ERROR_NONE = 0;
try
{
...
}
catch (System.DivideByZeroException dbz)
{
ERROR_NONE = ...;
return ERROR_NONE;
}
catch (AnotherException dbz)
{
ErrorCode = ...;
return ERROR_NONE;
}
return ERROR_NONE;
} // method
} // class
Its similar to your tuple result. Cheers.
UPDATE 1: Mention about exception handling.
UPDATE 2: explicit declare constants.
In javascript you can detect if a property is defined by using the undefined keyword:
if( typeof data.myProperty == "undefined" ) ...
How would you do this in C# using the dynamic keyword with an ExpandoObject and without throwing an exception?
According to MSDN the declaration shows it is implementing IDictionary:
public sealed class ExpandoObject : IDynamicMetaObjectProvider,
IDictionary<string, Object>, ICollection<KeyValuePair<string, Object>>,
IEnumerable<KeyValuePair<string, Object>>, IEnumerable, INotifyPropertyChanged
You can use this to see if a member is defined:
var expandoObject = ...;
if(((IDictionary<String, object>)expandoObject).ContainsKey("SomeMember")) {
// expandoObject.SomeMember exists.
}
An important distinction needs to be made here.
Most of the answers here are specific to the ExpandoObject which is mentioned in the question. But a common usage (and reason to land on this question when searching) is when using the ASP.Net MVC ViewBag. That's a custom implementation/subclass of DynamicObject, which won't throw an Exception when you check any arbitrary property name for null. Suppose you might declare a property like:
#{
ViewBag.EnableThinger = true;
}
Then suppose you wanted to check its value, and whether it's even set - whether it exists. The following is valid, will compile, won't throw any exceptions, and gives you the right answer:
if (ViewBag.EnableThinger != null && ViewBag.EnableThinger)
{
// Do some stuff when EnableThinger is true
}
Now get rid of the declaration of EnableThinger. Same code compiles and runs properly. No need for reflection.
Unlike ViewBag, ExpandoObject will throw if you check for null on a property that doesn't exist. In order to get MVC ViewBag's gentler functionality out of your dynamic objects, you'll need to use an implementation of dynamic that doesn't throw.
You could simply use the exact implementation in MVC ViewBag:
. . .
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = ViewData[binder.Name];
// since ViewDataDictionary always returns a result even if the key does not exist, always return true
return true;
}
. . .
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/DynamicViewDataDictionary.cs
You can see it being tied into MVC Views here, in MVC ViewPage:
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ViewPage.cs
The key to DynamicViewDataDictionary's graceful behavior is the Dictionary implementation on ViewDataDictionary, here:
public object this[string key]
{
get
{
object value;
_innerDictionary.TryGetValue(key, out value);
return value;
}
set { _innerDictionary[key] = value; }
}
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/ViewDataDictionary.cs
In other words, it always returns a value for all keys, regardless of what's in it - it simply returns null when nothing's there. But, ViewDataDictionary has the burden of being tied to MVC's Model, so it's better to strip out just the graceful dictionary parts for use outside MVC Views.
It's too long to really post all the guts here - most of it just implementing IDictionary - but here's a dynamic object (class DDict) that doesn't throw for null checks on properties that haven't been declared, on Github:
https://github.com/b9chris/GracefulDynamicDictionary
If you just want to add it to your project via NuGet, its name is GracefulDynamicDictionary.
I wanted to create an extension method so I could do something like:
dynamic myDynamicObject;
myDynamicObject.propertyName = "value";
if (myDynamicObject.HasProperty("propertyName"))
{
//...
}
... but you can't create extensions on ExpandoObject according to the C# 5 documentation (more info here).
So I ended up creating a class helper:
public static class ExpandoObjectHelper
{
public static bool HasProperty(ExpandoObject obj, string propertyName)
{
return obj != null && ((IDictionary<String, object>)obj).ContainsKey(propertyName);
}
}
To use it:
// If the 'MyProperty' property exists...
if (ExpandoObjectHelper.HasProperty(obj, "MyProperty"))
{
...
}
UPDATED: You can use delegates and try to get a value from the dynamic object property if it exists. If there is no property, simply catch the exception and return false.
Take a look, it works fine for me:
class Program
{
static void Main(string[] args)
{
dynamic userDynamic = new JsonUser();
Console.WriteLine(IsPropertyExist(() => userDynamic.first_name));
Console.WriteLine(IsPropertyExist(() => userDynamic.address));
Console.WriteLine(IsPropertyExist(() => userDynamic.last_name));
}
class JsonUser
{
public string first_name { get; set; }
public string address
{
get
{
throw new InvalidOperationException("Cannot read property value");
}
}
}
static bool IsPropertyExist(GetValueDelegate getValueMethod)
{
try
{
//we're not interesting in the return value. What we need to know is whether an exception occurred or not
getValueMethod();
return true;
}
catch (RuntimeBinderException)
{
// RuntimeBinderException occurred during accessing the property
// and it means there is no such property
return false;
}
catch
{
//property exists, but an exception occurred during getting of a value
return true;
}
}
delegate string GetValueDelegate();
}
The output of the code is the following:
True
True
False
I answered a very similar question recently: How do I reflect over the members of dynamic object?
Shortly, ExpandoObject is not the only dynamic object you might get. Reflection would work for static types (types that do not implement IDynamicMetaObjectProvider). For types that do implement this interface, reflection is basically useless. For ExpandoObject, you can simply check whether the property is defined as a key in the underlying dictionary. For other implementations, it might be challenging and sometimes the only way is to work with exceptions. For details, follow the link above.
Why you do not want to use Reflection to get set of type properyes? Like this
dynamic v = new Foo();
Type t = v.GetType();
System.Reflection.PropertyInfo[] pInfo = t.GetProperties();
if (Array.Find<System.Reflection.PropertyInfo>(pInfo, p => { return p.Name == "PropName"; }). GetValue(v, null) != null))
{
//PropName initialized
}
This extension method checks for the existence of a property and then returns the value or null. This is useful if you do not want your applications to throw unnecessary exceptions, at least ones you can help.
public static object Value(this ExpandoObject expando, string name)
{
var expandoDic = (IDictionary<string, object>)expando;
return expandoDic.ContainsKey(name) ? expandoDic[name] : null;
}
If can be used as such :
// lookup is type 'ExpandoObject'
object value = lookup.Value("MyProperty");
or if your local variable is 'dynamic' you will have to cast it to ExpandoObject first.
// lookup is type 'dynamic'
object value = ((ExpandoObject)lookup).Value("PropertyBeingTested");
Depending on your use case, if null can be considered as being the same as undefined, you can turn your ExpandoObject into a DynamicJsonObject.
dynamic x = new System.Web.Helpers.DynamicJsonObject(new ExpandoObject());
x.a = 1;
x.b = 2.50;
Console.WriteLine("a is " + (x.a ?? "undefined"));
Console.WriteLine("b is " + (x.b ?? "undefined"));
Console.WriteLine("c is " + (x.c ?? "undefined"));
Output:
a is 1
b is 2.5
c is undefined
(authorDynamic as ExpandoObject).Any(pair => pair.Key == "YourProp");
Hey guys stop using Reflection for everything it costs a lots of CPU cycles.
Here is the solution:
public class DynamicDictionary : DynamicObject
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
public int Count
{
get
{
return dictionary.Count;
}
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
string name = binder.Name;
if (!dictionary.TryGetValue(binder.Name, out result))
result = "undefined";
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
dictionary[binder.Name] = value;
return true;
}
}
Try this one
public bool PropertyExist(object obj, string propertyName)
{
return obj.GetType().GetProperty(propertyName) != null;
}