Create Dynamic Assembly On New App Domain - c#

I am trying to create a dynamic assembly on a separate app domain as shown here:
string webProfilesNamespace = ConfigurationManager.AppSettings["Profiles.Web.Namespace"];
AssemblyName webAName = new AssemblyName(webProfilesNamespace);
AppDomain webDomain = AppDomain.CreateDomain("WebDomain");
AssemblyBuilder webAsmBuilder = webDomain.DefineDynamicAssembly(webAName, AssemblyBuilderAccess.RunAndSave);
The problem is I keep getting this error when I call DefineDynamicAssebly:
Type 'System.Reflection.Emit.AssemblyBuilder' in assembly 'mscorlib,
Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is
not marked as serializable.
What do I have to do in order to be able to define dynamic assemblies on a newly created app domain?

Call DefineDynamicAssembly in the new app domain. Maybe do that using AppDomainCallback. I forgot what the method was called.

Related

Could not load type 'System.Security.Cryptography.SHA512CryptoServiceProvider' from assembly Version=2.4.0.0, Culture=neutral

I load Cryptography Providers dynamically using this code
string hashAlgoTypeString =
ConfigurationManager.AppSettings[HashAlgorithmProviderConfiguration];
if (hashAlgoTypeString != null)
{
Type hashAlgoType = Type.GetType(hashAlgoTypeString, true);
return (HashAlgorithm) Activator.CreateInstance(hashAlgoType);
}
The hashAlgoTypeString is a full qualified name to one of CryptoServiceProviders set in my Web.config
I don't have any problems loading these
System.Security.Cryptography.DESCryptoServiceProvider
System.Security.Cryptography.DSACryptoServiceProvider
System.Security.Cryptography.MD5CryptoServiceProvider
System.Security.Cryptography.RC2CryptoServiceProvider
System.Security.Cryptography.RNGCryptoServiceProvider
System.Security.Cryptography.RSACryptoServiceProvider
System.Security.Cryptography.SHA1CryptoServiceProvider
System.Security.Cryptography.TripleDESCryptoServiceProvider
However, the following CryptoServiceProviders all throw the "Could not load type" exception.
System.Security.Cryptography.AesCryptoServiceProvider
System.Security.Cryptography.SHA256CryptoServiceProvider
System.Security.Cryptography.SHA384CryptoServiceProvider
System.Security.Cryptography.SHA512CryptoServiceProvider
What could be the issue with these four providers?
I'm running Windows 7 x64 with .NET 4.5.2
In GAC
System.Security v2.0.0.0
mscorlib v2.0.0.0 for x86 and AMD64
Edit
I am able to instantiate all four
var Aes = new System.Security.Cryptography.AesCryptoServiceProvider();
var sha256 = new System.Security.Cryptography.SHA256CryptoServiceProvider();
var sha384 = new System.Security.Cryptography.SHA384CryptoServiceProvider();
var sha512 = new System.Security.Cryptography.SHA512CryptoServiceProvider();
and use them from my code without issues.
They are not defined in the same dll!
The ones that work are in mscorlib.dll, whereas the ones that don't work are in System.Core.dll
Probably if you add a reference to System.Core.dll it will work.
The issue was in the value returned from Web.config
string hashAlgoTypeString =
ConfigurationManager.AppSettings[HashAlgorithmProviderConfiguration];
Instead of
System.Security.Cryptography.SHA256CryptoServiceProvider
it should be fully qualified name
System.Security.Cryptography.SHA512CryptoServiceProvider, System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

Instantiating a class produces ReflectionTypeLoadException at Assembly.GetTypes()

I discovered that after my application generates Telerik report
var result = new ReportProcessor().RenderReport("PDF", new InstanceReportSource { ReportDocument = new MyTelerikReport(data) }, null);
var stream = new MemoryStream(result.DocumentBytes);
return CreateHttpFileResponse("MyReport.pdf", stream, "application/pdf");
I am not able to get all types within CurrentDomain
var typesWithAttribute = (from a in AppDomain.CurrentDomain.GetAssemblies()
from t in a.GetTypes() //error appears here
//some filtering logic
select t).ToList();
I am getting error
System.Reflection.ReflectionTypeLoadException: Unable to load one or
more of the requested types. Retrieve the LoaderExceptions property
for more information.
LoaderExceptions:
System.IO.FileNotFoundException: Could not load file or assembly
'DocumentFormat.OpenXml, Version=2.0.5022.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The
system cannot find the file specified. File name:
'DocumentFormat.OpenXml, Version=2.0.5022.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35'
After some investigation I found that assembly that fails to load: Telerik.Reporting.OpenXmlRendering, Version=8.0.14.311, Culture=neutral, PublicKeyToken=a9d7983dfcc261be and that assembly doesn't exists in AppDomain.CurrentDomain.GetAssemblies() before I generate report (I assume that assembly loaded dynamically by Telerik.Reporting, Version=8.0.14.311, Culture=neutral, PublicKeyToken=a9d7983dfcc261be).
I could filter out that assembly as I don't need any types from that but I am a bit worried about fact of having assemblies in domain that cannot be loaded - seems a bit wrong to me.
Could someone explain what there happens? Is it my issue or that is fault of 3rd party library that doesn't load all required assemblies?
The issue is not the assembly but the Type coming from a dependent assembly that has not been loaded.
If the GetTypes method is called on an assembly and a type in that assembly is dependent on a type in an assembly that has not been loaded (for example, if it derives from a type in the second assembly), a ReflectionTypeLoadException is thrown.
http://msdn.microsoft.com/en-us/library/system.reflection.assembly.gettypes(v=vs.110).aspx

Create a application like Visual studio object Browser

I want to develop an application like Visual studio Object Browser, i.e. user will enter something like System.Text namespace or system classes. After button click, we have to find out all classes, functions, properties etc. inside the "System.Text".
I tried the following, but that failed.
Assembly SampleAssembly;
SampleAssembly = Assembly.Load("System.Text");
Type[] Types = SampleAssembly.GetTypes();
// Display all the types contained in the specified assembly.
StringBuilder str = new StringBuilder();
foreach (Type oType in Types)
{
str.Append(oType.Name.ToString() + "</br>");
}
divAsseblyData.InnerHtml = str.ToString();
'System.Text' is a namespace not an assembly so i assume you want to load the assembly 'System'.
To use Assembly.Load() with a string parameter you need to pass the fully qualified name of the assembly.
To obtain the fully qualified name you can do something like this:
Assembly SampleAssembly;
SampleAssembly = Assembly.Load(typeof(System.Activator).Assembly.FullName);
// get the type of some random object in the assembly (Activator) and then
// call .Assembly.FullName which returns the fully qualified name of the assembly
Or you can press Win + R, type "Assembly" and enter, then right click -> proprieties on the assembly which you need and set manually the proprieties in code in the format:
"mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
SampleAssembly = Assembly.Load("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");

Unable to load executing assembly into new AppDomain, FileNotFoundException

I am trying to host a text template class proxy inside a new AppDomain.
I have some old scripting code that does something similar, that contains this working code:
_ScriptAppDomain = AppDomain.CreateDomain(scriptDomainFriendlyName);
_ScriptProxy = (IScriptEngineProxy)_ScriptAppDomain.CreateInstanceAndUnwrap(
Assembly.GetExecutingAssembly().FullName,
"LVK.Scripting.ScriptEngineProxy");
However, when I try this with my new class, with the following
_TemplateDomain = AppDomain.CreateDomain(templateDomainFriendlyName);
_TemplateProxy = (ITemplateProxy)_TemplateDomain.CreateInstanceAndUnwrap(
Assembly.GetExecutingAssembly().FullName,
"TextTemplate.TemplateProxy");
I just get "FileNotFoundException", with the following details:
Could not load file or assembly 'TextTemplate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bb70a2e62a722ace' or one of its dependencies. The system cannot find the file specified.
What am I missing?
Basically, I have a Template class in the TextTemplate namespace (and assembly), which tries to load a TemplateProxy class (descending from MarshalByRefObject) into the new appdomain, but it appears my main assembly is not loaded into this domain.
This works if I use the older code, but not with this new one, but I can't spot the difference.
Here's some more details:
Assembly is not registered with the GAC (neither was the old one, which works)
I have not overridden any AssemblyResolve event (neither did the old one, which works)
I'm not averse to handling the AssemblyResolve event, if that is what is needed. I just found it odd that my old code worked, and this didn't.
Assumying your assembly is in the same directory as your current application base, try specifying Application Base:
AppDomain.CreateDomain(templateDomainFriendlyName, null,
new AppDomainSetup
{
ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase
});
If you don't know what you are doing, the best way to create a new domain is to copy all settings from the current one, like this:
var newDomain = AppDomain.CreateDomain("NAME",
AppDomain.CurrentDomain.Evidence,
AppDomain.CurrentDomain.SetupInformation);
I had similar issues, and making a copy resolved them for me

Can't do Assembly.Load(String) with a referenced assembly unless I instantiate a class within that assembly first. How to solve?

I have a very strange problem here. It looks like unless I instantiate a class within an assembly I get an assembly not found error.
For example:
Assembly.Load("something.blah, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
Type mqType = Type.GetType(query.Attribute(fullyQualifiedName + ", " + assemblyInfo);
Object mq = Activator.CreateInstance(mqType);
Throws a FileNotFound exception on Assembly.Load
This:
Assembly.Load("something.blah, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
new someClassInAssembly();
Type mqType = Type.GetType(query.Attribute(fullyQualifiedName + ", " + assemblyInfo);
Object mq = Activator.CreateInstance(mqType);
Works fine. Yes, even if it is instantiated after Assembly.Load, so it is clearly a problem during compilation. How do I explicitly make sure that the assembly is loaded and findable during runtime, is there a compilation setting somewhere, what do I need to do?
Make sure you're loading the assembly you think you're loading, by supplying the path:
AssemblyName an = AssemblyName.GetAssemblyName(filePath);
Assembly.Load(an);
Honestly, if its just a single reference or a handful, just add an explicit reference somewhere it will save you a lot of effort.
//Use a static constructor somewhere appropriate.
static someClass(){
new AssemblyYouCareAbout.Object();
}
The alternatives are along the lines of hauling dlls manually to the bin of your running process or to add the dlls to the gac. I'd rather use the not-so-elegant static constructor and move on.

Categories

Resources