LoadComponent() Vs. XamlReader.Load()? - c#

Related to an earlier question I asked, I've seen that there's both LoadComponent() and XamlReader.Load(). They're similar enough that I'm not quite sure which one I should use in what case.
So, in essence, what's the difference between the two?
Thanks!

MSDN:
LoadComponent
XamlReader.Load()
Speculation
I would guess that LoadComponent calls XamlReader.Load(). LoadComponent looks more like an application level service and is probably used by the application itself to load all of the xaml resources. XamlReader is the specific library call for what you want.
Think about it as LoadComponent is an Application Service where XamlReader is the library containing the functionality.

Application.LoadComponent:Application will first preload resources as a 'Package' and register it in PreloadedPackage class, when calling LoadComponent method, wpf first check if package exsits and resource exists, then check if resouse is xaml or baml, finally load the resource stream with provided BaseUri
If resource is baml, LoadComponent will use Baml2006Reader, otherwise use XamlReader to process resource stream.
XamlReader.Load can load xaml resources outside the assembly.

Related

.net automatic assembly resolve loads duplicate assembly

I have an executable that depends on a library. I also have a "loader" application, which loads the executable into a seperate AppDomain (my "sandbox") and runs it there. The library needs initialization from outside the sandbox, so I need to load the library before I load the executable. This works as expected, but when I now load the executable, the library is loaded another time, and the executable uses the uninitialized copy.
This only occurs if I load the library like this:
Assembly.Load(File.ReadAllBytes(assemblyFile.FullName));
instead of this:
Assembly.LoadFrom(assemblyFile.FullName);
However, using LoadFrom locks the file. I need to be able to delete/write the file, because my application needs to be able to reload the entire sandbox and all assemblies in it.
I also tried registering AppDomain.AssemblyResolve, but it is only called if it does not find the file, which isn't exactly what I want ...
Example log output:
Loading library X <- manual load
Initializing library X
Loading executable Y
Loading library X <- bad, i want to use the loaded X!
So my question is: How do I force .net to use the already loaded assembly instead of loading a duplicate?
From the remarks on Assembly.Load(Byte[]):
Note that this method overload always creates a new Assembly object with its own mapping.
You can't use that overload if you want to reuse your loaded assemblies (without extra work anyway - the Framework won't automatically do it for you here).
You might be able to use the Assembly.Load(string) or just Type.GetType(string) methods here, but I suspect that's still going to end up locking files you want to modify. I'm not really sure how to make sense of modifying those files at run time to be honest though - what's the expected behavior if you delete or change a loaded assembly? Reload it? Have the modified code entered into memory?
You might need to create some kind of assembly caching mechanism of your own. If the assemblies aren't that large and you can afford to keep them in memory, it might be something as simple as a Dictionary<string, Assembly> - and just check if the dictionary has your assembly before loading it, otherwise load it using Assembly.Load(Byte[]) the way you are now.
I ended up modifying my AppDomainSetup of the sandbox:
domainSetup.DisallowApplicationBaseProbing = true;
Now, AssemblyResolve will be called everytime (no autodiscover for assemblies). Now I can just load assemblies from a byte[] and cache them (thanks to #DanField who suggested caching assemblies)

Hiding types from being listed in Assembly.GetTypes in .net

Ive been looking everywhere for a possible solution to this but can't seem to find an answer. My issue is that I have a few classes that need to completely hidden from Assembly.getTypes, as I'm writing a plugin for an application, and it's picking up types that I need to remain hidden (this happens even if they are declared as private or internal classes).
anyone know how to either alter what assembly.GetTyes returns, or an ,aficionado attribute that will keep those types from being listed?
This is quite a hack and is very fragile, but could work.
Create 2 assemblies -- one for the plug-in and the second for the other types. The second would be placed in another known directory and loaded dynamically into the first when needed. (For example, via Assembly.LoadFrom.)
The first assembly would then be placed in the plug-in directory and only ever publish its types. This very fragile because you would likely have to hard-code a path to the second assembly and you run the risk of the file getting deleted or moved.
EDIT
#SLaks' comment takes away the fragility of this solution. If you embed the second assembly as a resource and load it at run-time, the app calling Assembly.GetTypes won't see the types you want hidden.
This is not possible.
Sorry.
Code that calls Assembly.GetTypes() should typically filter for only public types.
Welcome to managed code. Complete type information is necessary to .NET's type verifier. Only native code can be hidden from .NET metadata, and then you give up the portability and permissions supported by pure MSIL.

How to understand the context of execution my dll in runtime: WinForms, WinService or ASP.NET?

My assembly (service) had developed for using in the WinForms Context.
So if there are troubles somewhere, my dll will show error form with corresponding message.
But now I'm going to use it.
The code is very old and dirty, that's why I don't want to use pattern approaches, etc.
Anyway, I need to have 100% working way to determine, what context I have.
I'm in WinForm
I'm in WinService
I'm in Web
If I understand correctly, you are on the path to create a nightmare to maintain.
Your assembly should have no knowledge of who is consuming it. Imagine tomorrow there's another context on which your assembly is used, you'll have to change your code again and add more dependencies that shouldn't be there on the first place.
IMHO, you either create an OnError event, on which you call the appropriate delegate the consumers of your assembly designate for it, or at the very least you do something similar to what System.Console.Out does; that is, you create a property of type TextWriter which you use to log all errors by default, but allow the consumers of your assembly to have a setter for this property so that they can redirect the log to their own TextWriter and handle the messages as appropriate.
Does that make sense?

NullReferenceException from AlphaImage.CreateFromResource()

I am using the AlphaMobileControls library for the .NET Compact Framework. I am using AlphaImage.CreateFromResource(imageResourceName) to create an AlphaImage object. The problem is that this method is throwing a NullReferenceException. Looking at the code for this method, the problem is that this line of code is returning null:
MemoryStream stream =
(MemoryStream)Assembly.GetCallingAssembly().GetManifestResourceStream(imageResourceName);
This was working fine before, and now it is not and I can't figure out why. It seems that I am passing a valid resource name. It is a resource that I added using the Resources tab of the project properties. Also in the Resources folder the image file is there and the Build Action is set to Embedded Resource. I even used this code to retrieve the available resources, and the one I am using was one of the returned values:
string[] names = Assembly.GetCallingAssembly().GetManifestResourceNames();
Then I was thinking that maybe by the time the AlphaImage.CreateFromResource() method code is running the available resources might be different. So I modified the code to include the above statement and then throw an InvalidOperationException if the passed resource is not an available resource. When I run the program and step through the code with the debugger, the added code is not there anymore and an InvalidOperationException is not thrown and the code will run until the NullReferenceException occurs. I searched my projects to see if maybe there was a reference to another version of AlphaMobileControls other than the one with the modified code, but I could not find any.
Any help will be appreciated, thanks in advance!
Inspect the result from Assembly.GetCallingAssembly().GetManifestResourceNames(); and see whether the resource name you are looking for appears here. When it doesn't, your settings on the properties of the resource (specifically "Build action: Embedded resource") will probably be set incorrect. Otherwise, maybe a folder has been renamed and you need to change the value of imageResourceName.
Aren basically answered this for me with his comment. You need to call AlphaImage.CreateFromResource() from the assembly that has the required resource. Thanks Aren.
The change I made that caused this to stop working was that I moved the class that was calling AlphaImage.CreateFromResource() into a separate library from the one that had the image resource. Therefore Assembly.GetCallingAssembly() is returning the assembly that does not have the resource.

Design-Time Resourcedictionaries

I have created something like this and this.
In effect I have a dll which supplies me with a "styler" for my application - it contains all my basic styles as well as a factory to call StylerFactory.DefaultStyler.ApplyStyles(this) on an Application - which merges the supplied ResourceDictionaries with the existing. This way I don't need all the basic styles in my components, nor do I need explicit references to my sesource-xaml-files.
Now - while this is working real good. The Styles are (obviously) not visible during design-time
To my questions:
Was that approach wise, or would it have been better to deploy xaml-resources and use them in every app/window/control ?
Does someone see any possibility to apply my styles to the design-time display of VS2008 ?
In my opinion, it's an acceptable approach. The reason being, I haven't seen a better method.
In my own cases, I've loaded resource dictionaries at runtime using the code I described here, which I would assume would work for loading resources from other assemblies as well. The drawback is that the designer will not run this code first, meaning no style is applied by default, what you're experiencing.
To counteract this, I added a default <ResourceDictionary.MergedDictionaries> definition in each of my <Window.Resources> that I needed to edit at design-time. While this ends up being a bit redundant, this allowed me to have a working design-time Window while the proper MergedDictionary can be loaded later during runtime. Perhaps you can use this to find a better method.

Categories