I have the code like this
public class SomeClass
{
private static int staticField = 10;
}
The code never gets executed and staticField has default value 0. Also the code causes MVVMlight's SimpleIoc to throw an exception with code like this:
SimpleIoc.Default.Register<SomeClass>();
Above code causes MVVMLight to throw an exception saying
Cannot build instance: Multiple constructors found but none marked with PreferredConstructor.
This very bizarre. I'm using Win8 RTM x64 + VS2012 Express for Windows 8.
Statics are initialized one by one in the order as declared in the source code. Since the first static is initialized before the rest, during its initialization the rest of the static fields are null or default values.
Static constructor can initialize only static variable but non-static constructor can initialize both static and non-static variable.
You could call the main method of classA . i.e. ClassA. main(somestrArray) and it should do the initialization. But if you don't want to do that then you could create your junit test in the same package as the original class and you would be able to access the protected variables .
If you declare a static variable in a class, if you haven't initialized it, just like with instance variables compiler initializes these with default values in the default constructor. Yes, you can also initialize these values using the constructor.
This is definitely a bug in SimpleIoc of MVVMLight. I have tried it with LinqPad and the problem is when you add a static field to the class an static ctor is added by the field initializer.
The result is that the class SomeClass has two ctors for SimpleIoc, what results in the exception you described.
A Workaround would be to add a default constructor to the class and decorate it with the PreferredConstructorAttribute
but this will result in a dependency to SimpleIoc.
Other solution would be to change your static field to a constant value.
public class SomeClass
{
private const int staticField = 10;
}
or to use an overload of the Register method to provide a factory method for instance creation.
SimpleIoc.Default.Register<SomeClass>(() => new SomeClass())
I have submitted a bug report on the MVVM Light project on CodePlex
LinqPad (Test code):
void Main()
{
var x = GetConstructorInfo(typeof(SomeClass));
x.Dump();
x.IsStatic.Dump();
}
public class PreferredConstructorAttribute : Attribute{
}
public class SomeClass{
private static int staticField = 10;
}
private ConstructorInfo GetConstructorInfo(Type serviceType)
{
Type resolveTo = serviceType;
//#if NETFX_CORE
var constructorInfos = resolveTo.GetTypeInfo().DeclaredConstructors.ToArray();
constructorInfos.Dump();
//#else
// var constructorInfos = resolveTo.GetConstructors();
//constructorInfos.Dump();
//#endif
if (constructorInfos.Length > 1)
{
var preferredConstructorInfos
= from t in constructorInfos
//#if NETFX_CORE
let attribute = t.GetCustomAttribute(typeof (PreferredConstructorAttribute))
//#else
// let attribute = Attribute.GetCustomAttribute(t, typeof(PreferredConstructorAttribute))
//#endif
where attribute != null
select t;
preferredConstructorInfos.Dump();
var preferredConstructorInfo = preferredConstructorInfos.FirstOrDefault ( );
if (preferredConstructorInfo == null)
{
throw new InvalidOperationException(
"Cannot build instance: Multiple constructors found but none marked with PreferredConstructor.");
}
return preferredConstructorInfo;
}
return constructorInfos[0];
}
// Define other methods and classes here
The problem is the line
var constructorInfos = resolveTo.GetTypeInfo().DeclaredConstructors.ToArray();
that returns an array with 2 ConstructorInfos both defined without the PreferredConstructorAttribute which results in the exception.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With