I have built an assembly that make calls to the ClosedXML library. Everything works perfectly until I have to export large Excel files, then things go south and I receive the following exception:
System.IO.IsolatedStorage.IsolatedStorageException: Unable to determine the identity of domain.
at System.IO.IsolatedStorage.IsolatedStorage._GetAccountingInfo(Evidence evidence, Type evidenceType, IsolatedStorageScope fAssmDomApp, Object& oNormalized)
at System.IO.IsolatedStorage.IsolatedStorage.GetAccountingInfo(Evidence evidence, Type evidenceType, IsolatedStorageScope fAssmDomApp, String& typeName, String& instanceName)
at System.IO.IsolatedStorage.IsolatedStorage._InitStore(IsolatedStorageScope scope, Evidence domainEv, Type domainEvidenceType, Evidence assemEv, Type assemblyEvidenceType, Evidence appEv, Type appEvidenceType)
at System.IO.IsolatedStorage.IsolatedStorage.InitStore(IsolatedStorageScope scope, Type domainEvidenceType, Type assemblyEvidenceType)
at System.IO.IsolatedStorage.IsolatedStorageFile.GetStore(IsolatedStorageScope scope, Type domainEvidenceType, Type assemblyEvidenceType)
at MS.Internal.IO.Packaging.PackagingUtilities.ReliableIsolatedStorageFileFolder.GetCurrentStore()...
So, after some research, I found some info on how to address the above exception, which is detailed in the questions below:
Unable to determine the identity of domain using System.IO.Packaging
Isolated Storage Exception: Unable to determine the identity of domain
As suggested in the answers to the questions above, I made sure that all of the classes in my custom assembly inherit from MarshalByRefObject
and are marked as Serializable
.
I have also added a custom assembly ResolveEventHandler
.
Saying that, because I am loading the assembly from a file at runtime (this is done because I do not have the option of adding it to the GAC), I am having trouble figuring out how to correctly implement the new domain and its resolve event. When I execute the code below, I recieve following error:
repository.GetWorkFlows()
is called:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: ''System.MarshalByRefObject' does not contain a definition for 'GetWorkFlows''
Code:
using System;
using System.Data.SqlClient;
using System.Reflection;
namespace ST_1736b3ab1e134250a6c05bffb44d449f
{
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
public Assembly CustomResolveEventHandler(object sender, ResolveEventArgs args)
{
Assembly assembly = null;
try
{
assembly = LoadAssembly(args, assembly);
}
catch (Exception exception)
{
Dts.Log(exception.ToString(), 0, new byte[0]);
throw;
}
Dts.Log("Exiting CurrentDomain_AssemblyResolve", 0, new byte[0]);
return assembly;
}
public Assembly LoadAssembly(ResolveEventArgs args, Assembly assembly)
{
Dts.Log(string.Format("Entering CurrentDomain_AssemblyResolve with args.Name [{0}]", args.Name), 0, new byte[0]);
string referencedAssembliesFilePath = Dts.Variables["$Package::referencedAssembliesFilePath"].Value.ToString();
var assemblyName = string.Format("{0}.dll", args.Name.Split(',')[0]);
Dts.Log("Assembly Name: " + assemblyName, 0, new byte[0]);
var assemblyFilePath = System.IO.Path.Combine(referencedAssembliesFilePath, assemblyName);
if (System.IO.File.Exists(assemblyFilePath))
{
Dts.Log(string.Format("Currently Loading [{0}]", assemblyFilePath), 0, new byte[0]);
assembly = Assembly.LoadFile(assemblyFilePath);
}
else
{
Dts.Log(string.Format("Could Not Find Assembly File [{0}].", assemblyFilePath), 0, new byte[0]);
}
return assembly;
}
public void Main()
{
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory.ToString();
Evidence evidence = new Evidence();
evidence.AddHostEvidence(new Zone(System.Security.SecurityZone.MyComputer));
AppDomain domain = AppDomain.CreateDomain("SeparateDomain", evidence, setup);
separateDomain.AssemblyResolve += new ResolveEventHandler(CustomResolveEventHandler);
const string referencedAssemblyName = "SSISDataExportManager";
string query = Dts.Variables["$Package::queryGetDataExportWorkFlowTasks"].Value.ToString();
dynamic repository = separateDomain.CreateInstanceAndUnwrap(referencedAssemblyName, referencedAssemblyName + "." + "DataExportManagerRepository");
using (SqlConnection connection = (SqlConnection)Dts.Connections["DbConnection"].AcquireConnection(Dts.Transaction))
{
if (connection.State == System.Data.ConnectionState.Closed) connection.Open();
//***Exception thrown here***
dynamic workflows = repository.GetWorkFlows(connection, query, 60);
dynamic factory = separateDomain.CreateInstanceAndUnwrap(referencedAssemblyName, "DataExportWorkflowSessionFactory");
dynamic session = factory.CreateSession(workflows);
session.Execute(connection);
}
Dts.TaskResult = (int)ScriptResults.Success;
}
#region ScriptResults declaration
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
}
}
I assume that this is because I need to explicitly cast to the types in my custom assembly, but again, I cannot do this due to it begin dynamically loaded.
What am I missing? Is there another way to do this, or is this even possible?