The method should return true if an "ArgumentNullException" is thrown and set "exceptionMessage" parameter to an exception message; otherwise the method should return false.
public static bool CatchArgumentNullException(object obj, out string exceptionMessage)
{
exceptionMessage = string.Empty;
try
{
if (obj is null)
{
throw new ArgumentNullException(exceptionMessage);
}
}
catch (Exception)
{
}
return false;
}
The method returns false. Why? How to return true?
Code corrected
public static bool CatchArgumentNullException(object obj, out string exceptionMessage)
{
exceptionMessage = string.Empty;
try
{
if ( obj is null )
throw new ArgumentNullException();
}
catch ( Exception ex )
{
exceptionMessage = ex.Message;
return true;
}
return false;
}
Test
object obj1 = null;
object obj2 = new object();
if ( CatchArgumentNullException(obj1, out var msg1) )
Console.WriteLine("obj1: " + msg1);
else
Console.WriteLine("obj1 is not null");
if ( CatchArgumentNullException(obj2, out var msg2) )
Console.WriteLine("obj2: " + msg2);
else
Console.WriteLine("obj2 is not null");
Output
obj1: La valeur ne peut pas ĂȘtre null. // The value can't be null.
obj2 is not null
Improvement
public static bool IsArgumentNull(object instance, string name, out string errorMessage)
{
errorMessage= string.Empty;
try
{
if ( instance is null )
throw new ArgumentNullException(name);
}
catch ( Exception ex )
{
errorMessage= ex.Message;
return true;
}
return false;
}
object obj1 = null;
object obj2 = new object();
if ( IsArgumentNull(obj1, nameof(obj1), out var msg1) )
Console.WriteLine(msg1);
else
Console.WriteLine("obj1 is not null");
if ( IsArgumentNull(obj2, nameof(obj2), out var msg2) )
Console.WriteLine(msg2);
else
Console.WriteLine("obj2 is not null");
The value can't be null.
Name of the parameter : obj1
obj2 is not null
Now this is a method that returns true if an object is null and we have a standard and localized system message including the variable name.
You need to add return in catch statement
You can change code as below depending if you only want to catch ArgumentNullException or all type of exceptions. Your current catch statement is for all kind of exceptions.
public static bool CatchArgumentNullException(object obj, out string exceptionMessage)
{
exceptionMessage = string.Empty;
try
{
if (obj is null)
{
throw new ArgumentNullException(exceptionMessage);
}
}
catch (ArgumentNullException ex)
{
return true;
}
catch (Exception e)
{
return true;
}
return false;
}
Related
I'm unit testing code for an application and I'm confused on how to test try/catch exceptions. What would be a good approach for testing this method?
public static Exception Create<TException>(string format, params object[] args) where TException : Exception
{
var type = typeof(TException);
try
{
if (type == typeof(ArgumentOutOfRangeException))
{
return (TException)Activator.CreateInstance(type, String.Empty, String.Format(format, args));
}
if (type == typeof(ArgumentNullException))
{
var name = format;
return (TException)Activator.CreateInstance(type, String.Empty, Constants.Strings.ValueCannotBeNull.FormatWith(name));
}
return (TException)Activator.CreateInstance(type, String.Format(format, args));
}
catch (MissingMethodException)
{
try
{
return (TException)Activator.CreateInstance(type);
}
catch (MissingMethodException ex)
{
return new Exception(ParameterlessConstructorMissing.FormatWith(type), ex);
}
}
}
I have a base page which I inherit from.
public class BasePage : System.Web.UI.Page
{
protected readonly ValueExtractor ValueExtractor;
protected sealed override HttpContext Context => base.Context;
public BasePage()
{
ValueExtractor = new ValueExtractor(new HttpContextWrapper(Context));
ClientTimeZone = new TimeZoneHelper(OrganizationId);
}
public int OrganizationId
{
get { return ValueExtractor.ExtractValFromSession<int>("OrgId"); }
set { Session["OrgId"] = value; }
}
}
The problem that I'm experiencing is that OrganizationId returns 0.
The ValueExtractor.ExtractValFromSession looks like this
public T ExtractValFromSession<T>(string key, bool throwException = true)
{
var ret = default(T);
var typeParameterType = typeof(T);
if (_context.Session == null) return ret; // The problem occurs here because Session is null
var val = _context.Session[key];
if (val != null)
{
try
{
if (typeParameterType == typeof(int))
{
int r;
int.TryParse(val.ToString(), out r);
ret = (T)Convert.ChangeType(r, typeof(T), CultureInfo.InvariantCulture);
}
else if (typeParameterType == typeof(bool))
{
bool r;
bool.TryParse(val.ToString(), out r);
ret = (T)Convert.ChangeType(r, typeof(T), CultureInfo.InvariantCulture);
}
else if(typeParameterType == typeof(string))
ret = (T)Convert.ChangeType(val.ToString(), typeof(T), CultureInfo.InvariantCulture);
else
ret = (T)Convert.ChangeType(val, typeof(T), CultureInfo.InvariantCulture);
}
catch (Exception ex)
{
throw new ApplicationException($"ExtractValFromSession error: {ex.Message}");
}
}
else
{
return ret;
}
return ret;
}
You can't access session in constructors of pages, you will need to move this code to page_load or other methods of the page lifecycle.
More info can be the page lifecycle docs
I am creating a new Asp.Net Core solution based on an existing Asp.Net 4.5 solution.
The current solution uses Microsoft Unity Container and the Infrastructure has references to the Service Locator.
I want to get rid of the Service Locator and avoid referencing specific DI containers in my new Infrastructure.
I'm having an issue coming up with a good way to replace the current Command/Query/Event Dispatcher without any DI container dependencies.
Here is my Dispatcher class
public class Dispatcher : IDispatcher
{
private const string HandleMethodName = "Handle";
public TResponse Request<TResponse>(IQuery<TResponse> query)
{
Type queryType = query.GetType();
// used for when OperationResult<object> was used
Type operationResultTrueReturnType = typeof(TResponse);
if (operationResultTrueReturnType == typeof(object))
{
operationResultTrueReturnType = queryType.GetInterface(typeof(IQuery<>).Name).GenericTypeArguments[0];
}
Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), operationResultTrueReturnType);
return ExecuteHandler<TResponse>(handlerType, query, queryType);
}
public OperationResult Submit(ICommand command)
{
Type commandType = command.GetType();
var baseTypeAttribute = (CommandBaseTypeAttribute)commandType.GetCustomAttributes(typeof(CommandBaseTypeAttribute), false).FirstOrDefault();
if (baseTypeAttribute != null)
commandType = baseTypeAttribute.BaseType;
try
{
Type handlerType = typeof(ICommandHandler<>).MakeGenericType(commandType);
return ExecuteHandler<OperationResult>(handlerType, command, commandType);
}
catch (InvalidOperationException ex)
{
return new OperationResult(OperationResultStatus.Failure, ex.Message);
}
}
public OperationResult<TResult> Submit<TResult>(ICommand<TResult> command)
{
Type commandType = command.GetType();
var baseTypeAttribute = (CommandBaseTypeAttribute)commandType.GetCustomAttributes(typeof(CommandBaseTypeAttribute), false).FirstOrDefault();
if (baseTypeAttribute != null)
commandType = baseTypeAttribute.BaseType;
try
{
Type handlerType = typeof(ICommandHandler<,>).MakeGenericType(commandType, typeof(TResult));
return ExecuteHandler<OperationResult<TResult>>(handlerType, command, commandType);
}
catch (InvalidOperationException ex)
{
return new OperationResult<TResult>(OperationResultStatus.Failure, default(TResult), ex.Message);
}
}
public void Raise(IDomainEvent domainEvent)
{
Type domainEventType = domainEvent.GetType();
try
{
Type handlerType = typeof(ICommandHandler<>).MakeGenericType(domainEventType);
ExecuteHandler(handlerType, domainEvent, domainEventType);
}
catch (InvalidOperationException)
{
}
}
private static void ExecuteHandler(Type handlerType, object argument, Type argumentType)
{
object handler = ServiceLocator.Current.GetInstance(handlerType);
if (handler == null)
throw new ConfigurationErrorsException("Handler not registered for type " + argumentType.Name);
try
{
MethodInfo handleMethod = handlerType.GetMethod(HandleMethodName, new[] { argumentType });
handleMethod.Invoke(handler, new[] { argument });
}
catch (TargetInvocationException ex)
{
if (ex.InnerException != null)
throw ex.InnerException;
throw;
}
}
private static TReturnValue ExecuteHandler<TReturnValue>(Type handlerType, object argument, Type argumentType)
{
object handler = ServiceLocator.Current.GetInstance(handlerType);
if (handler == null)
throw new ConfigurationErrorsException("Handler not registered for type " + argumentType.Name);
try
{
MethodInfo handleMethod = handlerType.GetMethod(HandleMethodName, new[] { argumentType });
return (TReturnValue)handleMethod.Invoke(handler, new[] { argument });
}
catch (TargetInvocationException ex)
{
if (ex.InnerException != null)
throw ex.InnerException;
throw;
}
}
}
ExecuteHandler has the ServiceLocator call.
How can I handle this without using it?
I like the suggestion provided in the comments. If you want to abstract away the service locator then have the dispatcher explicitly depend on an abstract service provider (like IServiceProvider) that will be used to do resolutions.
public class Dispatcher : IDispatcher {
private readonly IServiceProvider serviceProvider;
public Dispatcher (IServiceProvider serviceProvider) {
this.serviceProvider = serviceProvider;
}
//...other code removed for brevity
private object GetService(Type serviceType) {
return serviceProvider.GetService(serviceType);
}
private void ExecuteHandler(Type handlerType, object argument, Type argumentType) {
object handler = GetService(handlerType);
if (handler == null)
throw new ConfigurationErrorsException("Handler not registered for type " + argumentType.Name);
try {
MethodInfo handleMethod = handlerType.GetMethod(HandleMethodName, new[] { argumentType });
handleMethod.Invoke(handler, new[] { argument });
} catch (TargetInvocationException ex) {
if (ex.InnerException != null)
throw ex.InnerException;
throw;
}
}
private TReturnValue ExecuteHandler<TReturnValue>(Type handlerType, object argument, Type argumentType) {
object handler = GetService(handlerType);
if (handler == null)
throw new ConfigurationErrorsException("Handler not registered for type " + argumentType.Name);
try {
MethodInfo handleMethod = handlerType.GetMethod(HandleMethodName, new[] { argumentType });
return (TReturnValue)handleMethod.Invoke(handler, new[] { argument });
} catch (TargetInvocationException ex) {
if (ex.InnerException != null)
throw ex.InnerException;
throw;
}
}
}
The dispatcher is now no longer tightly coupled to the service locator anti-pattern and allows for any derived provider to be used. This allows you to avoid referencing specific DI containers.
I added an IServiceProvider to the Dispatcher's constructor.
public class Dispatcher : IDispatcher
{
private const string HandleMethodName = "Handle";
private readonly IServiceProvider _serviceProvider;
public Dispatcher(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public TResponse Request<TResponse>(IQuery<TResponse> query)
{
Type queryType = query.GetType();
// used for when OperationResult<object> was used
Type operationResultTrueReturnType = typeof(TResponse);
if (operationResultTrueReturnType == typeof(object))
{
operationResultTrueReturnType = queryType.GetInterface(typeof(IQuery<>).Name).GenericTypeArguments[0];
}
Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), operationResultTrueReturnType);
return ExecuteHandler<TResponse>(handlerType, query, queryType);
}
public OperationResult Submit(ICommand command)
{
Type commandType = command.GetType();
var baseTypeAttribute = (CommandBaseTypeAttribute)commandType.GetCustomAttributes(typeof(CommandBaseTypeAttribute), false).FirstOrDefault();
if (baseTypeAttribute != null)
commandType = baseTypeAttribute.BaseType;
try
{
Type handlerType = typeof(ICommandHandler<>).MakeGenericType(commandType);
return ExecuteHandler<OperationResult>(handlerType, command, commandType);
}
catch (InvalidOperationException ex)
{
return new OperationResult(OperationResultStatus.Failure, ex.Message);
}
}
public OperationResult<TResult> Submit<TResult>(ICommand<TResult> command)
{
Type commandType = command.GetType();
var baseTypeAttribute = (CommandBaseTypeAttribute)commandType.GetCustomAttributes(typeof(CommandBaseTypeAttribute), false).FirstOrDefault();
if (baseTypeAttribute != null)
commandType = baseTypeAttribute.BaseType;
try
{
Type handlerType = typeof(ICommandHandler<,>).MakeGenericType(commandType, typeof(TResult));
return ExecuteHandler<OperationResult<TResult>>(handlerType, command, commandType);
}
catch (InvalidOperationException ex)
{
return new OperationResult<TResult>(OperationResultStatus.Failure, default(TResult), ex.Message);
}
}
private TReturnValue ExecuteHandler<TReturnValue>(Type handlerType, object argument, Type argumentType)
{
object handler = _serviceProvider.GetService(handlerType);
if (handler == null)
throw new ArgumentException("Handler not registered for type " + argumentType.Name);
try
{
MethodInfo handleMethod = handlerType.GetMethod(HandleMethodName, new[] { argumentType });
return (TReturnValue)handleMethod.Invoke(handler, new[] { argument });
}
catch (TargetInvocationException ex)
{
if (ex.InnerException != null)
throw ex.InnerException;
throw;
}
}
}
Then, injected it in Startup on the client.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ResolutionDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc();
// Domain Event Handlers
services.AddTransient<IEventHandler<RequestCreatedEvent>, RequestCreatedHandler>();
// Domain Event Dispatcher
services.AddSingleton<IDomainEventDispatcher, DomainEventDispatcher>();
// Units of Work
services.AddTransient<IResolutionUnitOfWork, ResolutionUnitOfWork>();
// Commands and Queries
services.AddTransient<ICommandHandler<CreateRequestCommand, Guid>, CreateRequestHandler>();
// Command and Query Dispatcher
services.AddSingleton<IDispatcher, Dispatcher>();
}
I have written a function that may throw various exceptions..
public class MyClass
{
private void Test(string param)
{
if (param.Length > 10)
throw new ArgumentException();
else if (param.Length > 20)
throw new OverflowException();
else if (string.IsNullOrWhiteSpace(param))
throw new ArgumentException();
else if (param.Length < 1)
throw new FormatException();
}
public void Call(string input)
{
try
{
Test(input);
}
catch (Exception ex)
{
HandleException(ex);
}
}
private void HandleException(Exception ex)
{
//Check if ex is of type ArgumentException
//ToDo..
//Check if ex is of type OverflowException
//ToDo...
//Check if ex is of type ArgumentException
//ToDo..
//Check if ex if of type FormatException
//ToDo..
}
}
Is it possible to have the HandleException(ex) private method so that i can handle all exceptions. Otherwise, I have to write separate exception blocks for each expcetions
private void HandleException(Exception ex)
{
if (ex is ArgumentException)
{
//ToDo..
}
else if (ex is OverflowException)
{
//ToDo..
}
else if (ex is FormatException)
{
//ToDo..
}
}
if the performance of "is vs as" is so important for you you can use this approach
private void HandleException(Exception ex)
{
ArgumentException argEx;
OverflowException ovfEx;
FormatException fmtEx;
if ((argEx = ex as ArgumentException) != null)
{
//ToDo..
}
else if ((ovfEx = ex as OverflowException) != null)
{
//ToDo..
}
else if ((fmtEx = ex as FormatException) != null)
{
//ToDo..
}
}
I want to be able to:
Check if an object has an indexing operator defined.
If it is defined, I want to be able to use it.
I want to implement this in the following code.
The code contains an object (MyObject) that offers a way to traverse through a multidimensional array or linked set of hash tables. Also it should prevent giving errors if a node in the requested path doesn't exist.
The part that I can't figure out is the commented part in the code:
public class MyObject
{
private object myObject = null;
public MyObject()
{
}
public MyObject(object value)
{
myObject = value;
}
public void setValue(object value)
{
myObject = value;
}
public object getValue()
{
return myObject;
}
public object this[string key]
{
get
{
if (myObject == null)
{
return new MyObject(null);
}
else
{
// determine what of type/class myObject is and if it has indexing operators defined
// if defined, access them and return the result
// else return null.
}
}
set
{
if (myObject == null)
{
// do nothing (or throw an exception);
}
else{
// determine what of type/class myObject is
// determine if that type/class has indexing operators defined
// if defined, access them and set the result there
// else do nothing (or throw an exception).
}
}
}
}
This is what I wish to accomplish:
// given these variables:
string loremIpsumString = "lorem ipsum dolor sit amet";
int[] digits = new int[10];
for (int i = 0; i <= 3; i++) digits[i] = i;
Hashtable outerHashtable = new Hashtable();
Hashtable innerHashtable = new Hashtable();
innerHashtable.Add("contents", "this is inside");
outerHashtable.Add("outside", "this is outside");
outerHashtable.Add("inside", innerHashtable);
// I can already print this:
Response.Write( loremIpsumString ); // prints "lorem ipsum dolor sit amet"
Response.Write( digits[0] ); // prints "0"
Response.Write( digits[1] ); // prints "1"
Response.Write( digits[2] ); // prints "2"
Response.Write( outerHashtable["outside"] ); // prints "this is outside"
Response.Write( ((Hashtable)outerHashtable["inside"])["contents"] ); // prints "this is outside"
// But I want to be to do it this way:
MyObject myObject;
myObject = new MyObject(loremIpsumString);
Response.Write( myObject.getValue() ); // prints "lorem ipsum dolor sit amet"
Response.Write( myObject["unexistant"].getValue() ); // prints nothing/null
myObject = new MyObject(digits);
Response.Write( myObject[0].getValue() ); // prints "0"
Response.Write( myObject[1].getValue() ); // prints "1"
Response.Write( myObject[2].getValue() ); // prints "2"
myObject = new MyObject(outerHashtable);
Response.Write( myObject["outside"].getValue() ); // prints "this is outside"
Response.Write( myObject["inside"]["contents"].getValue() ); // prints "this is inside"
Response.Write( myObject["unexistant"].getValue() ); // prints nothing/null
Response.Write( myObject["unexistant"]["unexistant"]["unexistant"].getValue() ); // prints nothing/null
You can first check if it's inheriting IList to cover (generic) Lists and Arrays. If not you can use PropertyInfo.GetIndexParameters to check if it has an indexer instead:
get
{
if (myObject == null)
{
return null;
}
else
{
// not sure which index(es) you want
int index = 0;
Type t = myObject.GetType();
if (typeof(IList).IsAssignableFrom(t))
{
IList ilist = (IList)myObject;
return ilist[index];
}
else
{
var indexer = t.GetProperties()
.Where(p => p.GetIndexParameters().Length != 0)
.FirstOrDefault();
if (indexer != null)
{
object[] indexArgs = { index };
return indexer.GetValue(myObject, indexArgs);
}
else
return null;
}
}
}
DEMO (with a string which has an indexer to access the chars)
You can test if the object is a dictionary
public object this[string key]
{
get
{
var dict = myObject as IDictionary;
if (dict == null) {
return null;
}
if (dict.Contains(key)) {
return dict[key];
}
return null;
}
set
{
var dict = myObject as IDictionary;
if (dict != null) {
dict[key] = value;
}
}
}
Note: If you have the control over the dictionary type to use, then prefer Dictionary<string,object> over Hashtable. Its handy method TryGetValue allows you to safely access it without first calling Contains and thus saves you from accessing it twice. Of cause you would then cast to Dictionary<string,object> instead of IDictionary.
var dict = myObject as Dictionary<string,object>;
if (dict == null) {
return null;
}
object result;
dict.TryGetValue(key, out result); // Automatically sets result to null
// if an item with this key was not found.
return result;
For others looking for the answer. Here is what I made of it with #TimSchmelter 's help.
So this is the code that I implemented in the get{} that I used in the code at the top of this screen, where in the top of this screen the get{} just contained comments.
get
{
if (myObject == null)
return new MyObject(null);
object returnValue = null;
bool foundReturnValue = false;
object[] indexArgs = { key };
Type myObjectType = myObject.GetType();
if (typeof(IList).IsAssignableFrom(myObjectType))
{
try
{
returnValue = ((IList)myObject)[((int)key)];
foundReturnValue = true;
}
catch (Exception) { }
}
if (!foundReturnValue)
{
foreach (PropertyInfo property in myObjectType.GetProperties())
{
ParameterInfo[] indexParameters = property.GetIndexParameters();
foreach (ParameterInfo indexParameter in indexParameters)
{
if (indexParameter.ParameterType.IsAssignableFrom(key.GetType()))
{
try
{
returnValue = property.GetValue(myObject, indexArgs);
foundReturnValue = true;
}
catch (Exception) { }
}
if (foundReturnValue == true)
break;
}
if (foundReturnValue == true)
break;
}
}
return new MyObject(returnValue);
}