Activator.CreateInstance(type) Throws Exception - c#

Actually it is very strange exception, because it happens only when I build the project as Release and does not happen at all when I choose Debug. In debug mode, the app works perfect and the following code works well.
Here is the code of my extension method:
public static T DeepClone<T>(this T source) where T : UIElement
{
T result;
// Get the type
Type type = source.GetType();
// Create an instance
result = Activator.CreateInstance(type) as T; //throws exception here only if I build project as (release)
CopyProperties<T>(source, result, type);
DeepCopyChildren<T>(source, result);
return result;
}
The exception is:
An exception of type 'System.MissingMethodException' occurred in
System.Private.Reflection.Execution.dll but was not handled in user
code
Additional information: MissingConstructor_Name,
Windows.UI.Xaml.Controls.RelativePanel. For more information, visit
http://go.microsoft.com/fwlink/?LinkId=623485
I've found some related questions to this exception, but they all are pointing to missing libraries or update libraries like this but didn't change anything in my app.

This problem is related to the fact that Release build of UWP apps uses the .NET native toolchain. In this mode reflection needs some hints to work properly. Aparently the constructor of the RelativePanel is not available for reflection.
Luckily there is a workaround for this as described in this blogpost.
In your UWP project's Properties folder is a file called default.rd.xml. Open it and add the following line inside the <Applications> element:
<Type Name="Windows.UI.Xaml.Controls.RelativePanel"
Dynamic="Required All" Activate="Required All" />
The Dynamic attribute should ensure reflection is possible and the Activate attribute should ensure the constructors are available for activation - which is key for your case.
This should include all members of RelativePanel for reflection and everything should work as expected.
You can see more details on the default.rd.xml file structure here.

Related

AppInstance.RedirectActivationTo() fails with "The group or resource is not in the correct state to perform the requested operation." error

I am trying to determine which instance of my multi-instance UWP application should be activated based on the argument passed to it:
var instances = AppInstance.GetInstances();
if (instances.Count() != 0)
{
instances[0].RedirectActivationTo();
}
I have tried placing the code in app.xaml.cs (OnActivated) and main.xaml.cs (OnNavigatedTo) and they both throw the "The group or resource is not in the correct state to perform the requested operation." error for which there appears to be no documentation.
How can I redirect the activation to a current instance?
The AppInstance class should be used in a main method. This is mentioned in the document: The AppInstance class is intended to be used in the Main method of the app. If this class is used later, the property values may be null, and the methods may fail.
To create a main method of UWP app, you will need to disable the defaulted main method which is generated automatically first. Please right click on your project and choose properties, in the Build tab, add DISABLE_XAML_GENERATED_MAIN to the Conditional Compilation Symbols.
Then you could add a new static class to your project and add a new static main mehtod in the class.
I found a blog which have detailed steps about how to use AppInstance.RedirectActivationTo method, you could take a look at: Multiple instances support for UWP apps (Part 2): Redirection
Besides if you want to redirect to an existing instance, it will be better to register the instance first.

Why are these Type objects not equal?

I have an application where I load plugins by reading their DLL file and then loading the bytes using AppDomain.CurrentDomain.Load(bytes). Note that the application and the plugin are loaded in the same AppDomain. The plugin contains several classes which register themselves in a service locator system using a static constructor.
Later, my main application tries to find and instantiate one of these service classes using the service locator, but it cannot find the class. Upon manual inspection, I can see that the registry entry is present in the locator, so it was registered, but for some unknown reason the types aren't equal.
I then put a breakpoint at the place where the type is registered and discovered the following weirdness:
How can typeof(IViewFor<CompactDashboardViewModel>) not be equal to itself?
I then tested a few more things:
t == t
true
typeof(IViewFor<CompactDashboardViewModel>) == typeof(IViewFor<CompactDashboardViewModel>)
true
t.AssemblyQualifiedName == typeof(IViewFor<CompactDashboardViewModel>).AssemblyQualifiedName
true
In fact, everything about these 2 Type objects seems to be equal, except the m_handle and m_cache fields.
typeof(IViewFor<CompactDashboardViewModel>).TypeHandle
{System.RuntimeTypeHandle}
Value: 0x08690784
m_type: {Name = "IViewFor`1" FullName = "ReactiveUI.IViewFor`1[[PluginMTSICS.ViewModel.CompactDashboardViewModel, PluginMTSICS, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}
t.TypeHandle
{System.RuntimeTypeHandle}
Value: 0x0f8cf5a8
m_type: {Name = "IViewFor`1" FullName = "ReactiveUI.IViewFor`1[[PluginMTSICS.ViewModel.CompactDashboardViewModel, PluginMTSICS, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}
Does anybody know what is happening here? I am using .NET 4.7.1.
I am trying to create an MCVE, but unsuccessfully so far.
Maybe this works:
Type t = typeof(IViewFor<CompactDashboardViewModel>);
//this should evaluate to true:
bool result = t.Equals(typeof(IViewFor<CompactDashboardViewModel>));
Type.Equals docs:
https://msdn.microsoft.com/en-us/library/3ahwab82(v=vs.110).aspx
EDIT:
After reading this post Type Checking: typeof, GetType, or is? i would expect this to work:
Type t = typeof(IViewFor<CompactDashboardViewModel>);
//this should evaluate to true:
bool result = t is IViewFor<CompactDashboardViewModel>;
OK, so I fixed the issue. Here is what I did:
My main application had a reference to a library project, which in turn referenced the plugin project. This probably caused the assembly to be loaded twice, in different load contexts (see links below for more info). I removed the reference. The problem was not fixed, and now weird stuff was happening such as typeof(CompactDashboardViewModel) == null.
My plugin loading code originally used appdomain.Load(bytes). I replaced this with Assembly.LoadFrom. typeof() now worked correctly, and works as expected. However, Type.GetType() still returns null sometimes.
I replaced Assembly.LoadFrom with Assembly.Load and added my plugin directory to the probing path using the <probing> tag in app.config. Everything works correctly now, however I can't load the plugins by filepath, as Assembly.Load requires the assembly name. Not ideal, but I can live with that.
Useful sources:
Best practices for assembly loading
<probing> element
Type.GetType() docs
LoadFrom isolation
Choosing a binding context

uwp app has dynamic variables, which causes the app to crash in release mode

in my uwp app I am using dynamic variables at many places, because the data is coming from the server backend api, so we want to keep it dynamic. it runs fine in Debug mode but I wanted to upload to store so I tried it on Release mode and it fails with following exception
system.reflection.missingmetadataexception
obviously this exception occurs, in one of my pages called "LoginPage.xaml.cs" at the first line where I am trying to use the dynamic data. following is the line which causes the exception.
ViewModel.backgroundURL = AppConfig.Login.background;
AppConfig here is a static object in a constants class. and its type is dynamic, I am succesfully get it from server API, but exception only occurs when I try to consume it in my app as you can see in the code line above.
after some research I found that using the following line in Default.rd.xml can solve this error I put the following line there.
<Namespace Name="bluebook.ViewModels" Seralize="All" />
as you can see I am putting this line in my directives tag as shown below.
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<!--
An Assembly element with Name="*Application*" applies to all assemblies in
the application package. The asterisks are not wildcards.
-->
<Assembly Name="*Application*" Dynamic="Required All" />
<!-- Add your application specific runtime directives here. -->
<Namespace Name="bluebook.ViewModels" Serialize="All" />
</Application>
</Directives>
I am trying to do the directives on ViewModels because the fields I am assigning to are in the ViewModel class. I also tried to do it on Views name space which has all the view classes like LoginPage and others, but in both cases the exception is still occuring, exactly at the same line.
Update 1
Exception Details
System.Reflection.MissingMetadataException: 'Reflection_InsufficientMetadata_NoHelpAvailable: EETypeRva:0x000a8990.
StackTrace : null
Source : null
Is "Serialize" misspelled in your directive file?
Try adding <Type Name="Microsoft.CSharp.RuntimeBinder.CSharpGetMemberBinder" Dynamic="Required All"/> to your Default.rd.xml.
(This answer may be relevant to you - answered by someone who works on .Net Native - Building with .NET Native tool chain causes error with missing property in dynamic object )

How to collect types from current solution using Visual Studio Extension?

I have created Visual Studio 2012 Package (using VS2012 SDK). This Extension (if installed on the client's IDE environment) should has, among other things, a functionality of collecting all specific types from currently opened solution which developer is working on. A similar feature is embedded in Visual Studio Designer for ASP.NET MVC Application Project, where developer implements a Model/Controller class, build a project, and then is able to access this type in Scaffolding UI (Designer's dropdown list). The corresponding features are also available in WPF, WinForms Visual Designers, etc.
Let's say that my extension has to collect all types from current solution, which implement ISerializable interface. The steps are following: Developer creates specific class, rebuild containing project/solution, then do some action provided by extension UI, thus involves performing ISerializabletypes collecting.
I have tried to implement collecting operation using reflection:
List<Type> types = AppDomain.CurrentDomain.GetAssemblies().ToList()
.SelectMany(s => s.GetTypes())
.Where(p => typeof(ISerializable).IsAssignableFrom(p) && !p.IsAbstract).ToList();
But above code causes System.Reflection.ReflectionTypeLoadException exception to be thrown:
System.Reflection.ReflectionTypeLoadException was unhandled by user code
HResult=-2146232830
Message=Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
Source=mscorlib
StackTrace:
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.RuntimeModule.GetTypes()
at System.Reflection.Assembly.GetTypes()
(...)
LoaderException: [System.Exception{System.TypeLoadException}]
{"Could not find Windows Runtime type 'Windows.System.ProcessorArchitecture'.":"Windows.System.ProcessorArchitecture"}
(...)
How can I properly implement operation of collecting specific types from currently built solution?
I was trying to do a similar thing and unfortunately the only way around this I've found so far is by doing the following (which I feel is a bit messy, but maybe with some tweaking for a specific situation might be ok)
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
IEnumerable<Type> types = assemblies.SelectMany(x => GetLoadableTypes(x));
...
public static IEnumerable<Type> GetLoadableTypes(Assembly assembly)
{
try
{
return assembly.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
return e.Types.Where(t => t != null);
}
}
This would give you all types, but you can filter out whatever you wish.
Referenced this post: How to prevent ReflectionTypeLoadException when calling Assembly.GetTypes()
I'm not sure if I understand you correctly, but if I am this will make it:
var assembly = Assembly.GetExecutingAssembly();
IEnumerable<Type> types =
assembly.DefinedTypes.Where(t => IsImplementingIDisposable(t))
.Select(t => t.UnderlyingSystemType);
........
private static bool IsImplementingIDisposable(TypeInfo t)
{
return typeof(IDisposable).IsAssignableFrom(t.UnderlyingSystemType);
}

Attempt by method 'System.Web.Helpers.Json..cctor()' to access method 'System.Web.Helpers.Json.CreateSerializer()' failed

I am using System.Web.Helpers.Json to deserialize some JSON into dynamic in NET 4. The following line fails with this error: TypeInitializationException: Attempt by method 'System.Web.Helpers.Json..cctor()' to access method 'System.Web.Helpers.Json.CreateSerializer()' failed.
var json = Json.Decode(response);
The response is lengthy but valid JSON. What could be the matter here? I have tried LINQPad with a short handcrafted JSON and it worked. Is this a configuration issue of some sort?
[EDIT]
Here is the actual sample JSON. It appears the content is pretty much irrelevant. When this is run in a brand new Console application or LINQPad, it works as expected. But if you try to run the same code from a brand new Windows Forms application, it barfs with the above error.
var json = Json.Decode("{\"r\":{\"0\":{\"id\":\"2\"},\"1\":{\"id\":\"33\"}}}");
[EDIT2]
Actually, it turns out this has nothing to do with project types. The exception is thrown if the project is being debugged. If it is simply run, the exception does not occur. Strange, eh?
I forgot about this question and I found my answer in the meantime. I think it was somewhere on Microsoft's Connect site but I am not sure. So let's share it now.
Basically, in order to workaround this problem you need to make sure "Enable the Visual Studio hosting process" is unchecked in your project's settings under Debug. I am not sure why it's happening but this is definitely a way to "fix" it. I stopped searching for answers once I found out about this. It was good enough for me.
This can also happen if you are running in a partial trust.
Check the exception description here for possible reasons.
I don't know if this will apply to you, since you are not running in a web context, but this is what that link describes:
This exception is thrown in situations such as the following:
A private, protected, or internal method that would not be accessible from normal compiled code is accessed from partially
trusted code by using reflection.
A security-critical method is accessed from transparent code.
The access level of a method in a class library has changed, and one or more assemblies that reference the library have not been
recompiled.
There is problem in the inbuilt json class.
If you want to achieve this in alternate way, please use the below code:
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new DynamicJavaScriptConverter[] { new DynamicJavaScriptConverter() });
var result = WrapObject(serializer.DeserializeObject(value)); // here you will have result.
private object WrapObject(object value)
{
IDictionary<string, object> values = value as IDictionary<string, object>;
if (values != null)
{
return new DynamicJsonObject(values);
}
object[] arrayValues = value as object[];
if (arrayValues != null)
{
return new DynamicJsonArray(arrayValues);
}
return value;
}
Further to Roland's answer: some assembly mismatches listed can be fixed in the AssemblyInfo.cs file.
The offending line in my AssemblyInfo was this:
[assembly: AllowPartiallyTrustedCallers]
Removing this allowed me to access the public property (on a public class) that I was trying to set from another assembly that had dynamically loaded this assembly.

Categories

Resources