Reflection.Assembly.CreateInstance(string) - c#

In .NET 4.0, if I have the following code:
....
T instantiatedClass;
try
{
instantiatedClass = (T)assembly.CreateInstance(classFullName);
}
catch (Exception ex)
{
errMsg = string.Format("Error creating an instance of type \"{0}\".", classes.First().FullName);
throw new ApplicationException(errMsg, ex);
}
Assuming that classFullName is a correct type in the assembly, and that the type "T" implements a public interface, is there any circumstance where 1) No exception would be thrown, and 2) instantiatedClass would be null?
Thanks for any help.

Based on your assumptions and if your type T is always an interface then a direct cast to T will throw an exception if the interface in question is not implemented by the created instance or if the type does not have a default constructor that can be called.
A better approach that avoids throwing an exception would be...
T interfaceVar = assembly.CreateInstance(classFullName) as T;
if (interfaceVar == null)
{
// oops, does not implement interface T
}
else
{
// yippee, it does implement interface T
}
You could use reflection on the target assembly to check if the required type exists, if it has a default constructor and if it implements the interface you are interested in. In that case you would avoid creating an instance at all, if all you want to know is if it has the specified interface.

If there is no default constructor or the assumption that classFullName is valid in the assembly is incorrect or anything prevents the CreateInstance call from calling a constructor an exception is thrown.
So the only way that this could fail for you is if the called constructor returns a null value. But this can't happen since if no exception is raised during construction, then the constructor call will return a reference to the new object, and if an exception is raised you catch it.

Related

What is the appropriate Exception to throw upon a runtime type mismatch in C#

Essentially I am creating a little IL injection DLL that uses MONO.CECIL and C#, primarily as a learning exercise for myself but also for my own future hobbyist use.
I am not particularly skilled with exceptions (or C#) and am unsure what the appropriate exception to throw is for when a runtime type mismatch occurs.
For example : I have a method that INJECTS a method call at a given point in a target DLL. The method takes as an arguement a Collection (parameters) to represent the variables to pass as parameters to the newly injected method call.
Before injecting I check for type parity between each member of the Collection (parameters) and the Collection from the method whose call I am injecting.
On a mismatch I want to throw an exception. But I could not really find any that fit. I would prefer to use existing exceptions where possible, rather than creating my own.
Here is the code :
private static bool ParameterParity(Collection<ParameterDefinition> p, Collection<VariableDefinition> v)
{
if (p.Count != v.Count)
{
return (false);
}
else
{
int index = 0;
foreach (ParameterDefinition parameter in p)
{
if (parameter.ParameterType.MetadataType != v[index].VariableType.MetadataType)
{
return (false);
}
index++;
}
}
return (true);
}
Here is the call where the exception will be thrown :
if (ParameterParity(source.Parameters, parameters) == false)
{
throw new NotImplementedException($"{Helper.AddParenthesis(nameof(PreInject), Helper.ParenthesisE.Square)}" +
$" : Parameter mismatch in TYPE or NUMBER" +
$". Functionality not supported.");
}
I temporarily have used the NOT IMPLEMENTED exception, but would prefer something more appropriate. A suggestion as to the appropriate Exception would be appreciated.
Thanks in advance.

Can a [pure] function throw an exception?

Is it OK for a function that can throw an exception to have the [pure] attribute?
According to
https://msdn.microsoft.com/en-us/library/system.diagnostics.contracts.pureattribute(v=vs.110).aspx
PureAttribute attribute
Indicates that a type or method is pure, that is, it does not make any
visible state changes.
So it's quite possible to throw an exception from such a method e.g.
// factorial is a pure function: no state will be changed,
// just a computation
[Pure]
public static BigInteger Factorial(BigInteger value) {
// We can't return infinity with BigInteger and that's why have to throw the exception
if (value < 0)
throw new ArgumentOutOfRangeException("value", "value must be non-negative");
...
}
And what if I call this pure method as
BigInteger result = Factorial(1000000000);
one of the possible outcomes is OutOfMemory exception thrown
You can throw an exception, you are not making any visible state changes. Here example from Reference source.
[Pure]
private void VerifyWritable() {
if (isReadOnly) {
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
}
Contract.EndContractBlock();
}
I agree with Dmitry.
According to documentation from msdn:
All methods that are called within a contract must be pure; that is, they must not update any preexisting state. A pure method is allowed to modify objects that have been created after entry into the pure method.
Throwing an exception is allowed and will not necessarily be considered as a changing the object state.

ConstructorArgument.Inject breaks where Kernel.Get works

Given the following classes:
interface IFoo { }
class Foo : IFoo { }
class Bar
{
public Bar(IFoo foo) { }
}
And the binding:
Bind<Bar>().ToConstructor(ctx => new Bar(ctx.Inject<Foo>()));
Calling kernel.Get<Bar>() throws the following exception:
An unhandled exception of type 'Ninject.ActivationException' occurred in Ninject.dll
Additional information: Error activating IFoo
No matching bindings are available, and the type is not self-bindable.
Activation path:
2) Injection of dependency IFoo into parameter foo of constructor of type Bar
1) Request for Bar
However, if I change my bindings to:
Bind<Bar>().ToMethod(ctx => new Bar(ctx.Kernel.Get<Foo>()));
I can get an instance of Bar as expected.
Why am I getting that exception? I was under the impression the two bindings are almost identical, and in both cases an instance of IFoo is never activated.
(Not) working fiddle can be seen here: https://dotnetfiddle.net/qmPFhr
This is not supported by ninject. The type specified in ctx.Inject<> must match the type of the constructor parameter exactly. Ninject is never actually executing your new Bar(...), it only analyses the expression to determine which constructor to use and how to inject the values.
There's two ways to adapt your code to make it work:
change the constructor of Bar to receive a Foo intead of an IFoo.
change the ToConstructor binding of Bar to have ctx.Inject<>() match the constructor of Bar (ctx.Inject<IFoo>()) and create a binding for IFoo:
.
Bind<IFoo>().To<Foo>();
Bind<Bar>().ToConstructor(ctx => new Bar(ctx.Inject<IFoo>()));
As per your request for documentation
No it's not documented in any other document than the source/api, that ctx.Inject<> is not actually executed, ever. However, it is quite obvious from the parameter of the method being an Expression<Func<..>> and not a Func<..>. If it would be executed, a Func<..> would suffice. Expression's are there so you can analyze their contents.
Also, when looking at the source of BindingBuilder.cs, the Inject<T1> method actually only does one thing: throwing an exception:
public T1 Inject<T1>()
{
throw new InvalidOperationException("This method is for declaration that a parameter shall be injected only! Never call it directly.");
}
Also see: http://ivanitskyi.blogspot.com/2013/06/linq-func-vs-expression.html
If, however, you're referring to documentation regarding that the type T at Inject<T> must be an exact match: The answer is no, again. I couldn't find any documentation about it. However, as it's open source, we can again resort to having a look at the implementation. Again, it's found in BindingBuilder.cs, which contains:
protected IBindingWhenInNamedWithOrOnSyntax<TImplementation> InternalToConstructor<TImplementation>(
Expression<Func<IConstructorArgumentSyntax, TImplementation>> newExpression)
{
var ctorExpression = newExpression.Body as NewExpression;
if (ctorExpression == null)
{
throw new ArgumentException("The expression must be a constructor call.", "newExpression");
}
this.BindingConfiguration.ProviderCallback = StandardProvider.GetCreationCallback(ctorExpression.Type, ctorExpression.Constructor);
this.BindingConfiguration.Target = BindingTarget.Type;
this.AddConstructorArguments(ctorExpression, newExpression.Parameters[0]);
return new BindingConfigurationBuilder<TImplementation>(this.BindingConfiguration, this.ServiceNames, this.Kernel);
}
And you can go from there an have a look at AddConstructorArguments and how that stuff works, and eventually you'll find out why it behaves as it does ;-)
(I'm not going to to that for you)

Is it acceptable/desire If I throw an error from callee rather than from caller

Is it acceptable/desire If I throw an error from callee rather than from caller? Or should I get the error info from callee and then throw the exception from caller? Which one is preferred/desire way?
public static List<ProductBuilder> GetProductBuilders(GetProductsRequest productsRequest)
{
List<ProductBuilder> productBuilders = new List<ProductBuilder>();
...
... // Some logics to populate productBuilders
if (productBuilders.Count == 0)
{
Logger.LogMessage(productsRequest.SessionId, "No ProductBuilders were created.");
throw new ProductException(ProductException.ExceptionCode.SaveFailed, "No Service has qualified.");
}
return productBuilders;
}
Your answer is stick to the Single responsibility principle.
In the example you provided the method GetProductBuilders has (at least) two responsibilities:
Populate the collection of objects
Validate the result count
If you refactor your code to:
public static List<ProductBuilder> PopulateProductBuilders(...)
{
// Logic to populate the collection
}
public static List<ProductBuilder> GetProductBuilders(GetProductsRequest productsRequest)
{
var productBuilders = PopulateProductBuilders();
if(!productBuilders.Any())
{
Logger.LogMessage(productsRequest.SessionId, "No ProductBuilders were created.");
throw new ProductException(ProductException.ExceptionCode.SaveFailed, "No Service has qualified.");
}
}
then it becomes clear which method should perform the validation on empty list and throw the exception.
In other words, if you separate the responsibilities of your methods you'll have a better picture of where to throw exceptions.
IMHO,
Your framework class code should throw exception if any your class is expecting some parameters from the client , otherwise client should handle the output returned.

C# interop - validate object exists

I would like to use a COM object in my application.
How can I make sure the object is registered in the machine?
The only solution I found (also on SO) was to use a try-catch block around the initialization:
try {
Foo.Bar COM_oObject = new Foo.Bar();
} catch (Exception ee) {
// Something went wrong during init of COM object
}
Can I do it in any other way?
I feel its wrong to deal with an error by expecting it and reporting it, I would rather know I will fail and avoid it to begin with.
You are using exception handling the right way: to fail gracefully from a specific situation that you know how to recover from.
There's not a problem with using try-catch in this case, but you could at least catch more specifically : ComException.
"I feel its wrong to deal with an error by expecting it and reporting it"
Isn't it exactly the purpose of try-catch? BTW, an Exception occurs when something really bad has happened and since it is a pretty bad thing that the COM object you are referring to is not registered, therefore, an Exception is the perfect solution. And you can't handle an exception in any other way.
I think this is the right way to do it.
If you know your component's ProgId. You could try this trick
comType = Type.GetTypeFromProgID(progID,true/*throw on error*/);
If you're doing this a lot and wish you had a non-exception throwing equivalent, try:
public static class Catching<TException> where TException : Exception
{
public static bool Try<T>(Func<T> func, out T result)
{
try
{
result = func();
return true;
}
catch (TException x)
{
// log exception message (with call stacks
// and all InnerExceptions)
}
result = default(T);
return false;
}
public static T Try<T>(Func<T> func, T defaultValue)
{
T result;
if (Try(func, out result))
return result;
return defaultValue;
}
}
So now you can do this:
Foo.Bar newObj;
if (!Catching<ComException>.Try(() => new Foo.Bar(), out newObj))
{
// didn't work.
}
Or if you have a default object stored in defaultMyInterface you'd use to implement an interface if there's nothing better:
IMyInterface i = Catching<ComException>.Try(() => new Foo.Bar() as IMyInterface,
defaultMyInterface);
You can also do this, in a completely different scenario:
int queueSize = Catching<MyParsingException>
.Try(() => Parse(optionStr, "QueueSize"), 5);
If Parse throws a MyParsingException, queueSize will default to 5, otherwise the returned value from Parse is used (or any other exception will propagate normally, which is usually what you want with an unexpected exception).
This helps to avoid breaking up the flow of the code, and also centralises your logging policy.

Categories

Resources