Home

Cannot compile typed context: Metadata file "VersantLinqPadDriver.dll" could not be found

edited April 2012
Hi Joe,

I was trying to run with my custom driver for Versant's object database and I was having trouble with some assembly loading. I've installed the driver by browsing for a new driver and adding my lpx file. That works and the driver dll is unpacked to:


C:\ProgramData\LINQPad\Drivers\DataContext\4.0\VersantLinqPadDriver (7680ed903fef1059)

When I attempt to use the driver, I get the "Cannot compile typed ..." error.

I found that if I put a copy of my driver in the same directory as LinqPad.exe or the cxInfo.CustomAssemblyPath directory then everything works fine. Somehow this doesn't seem like the right answer to me. It also works if I invoke LinqPad from the driver's VS2010 project when debugging.

Here's the stack trace from 4.40, but it looks about the same for 4.34 which is the version I had been using.
4.40.08 2012-04-12T19:37:03.6109547-05:00 Error opening DataContext - 
Exception: Cannot compile typed context: Metadata file 'VersantLinqPadDriver.dll' could not be found (line 0)

Server stack trace: 
   at Versant.LINQPadDriver.SchemaBuilder.BuildAssembly(String customAssemblyPath, String code, AssemblyName name)
   at Versant.LINQPadDriver.SchemaBuilder.GetSchemaAndBuildAssembly(DriverProperties props, AssemblyName name, String& nameSpace, String& typeName)
   at Versant.LINQPadDriver.DriverCommon.GetSchemaAndBuildAssembly(IConnectionInfo cxInfo, AssemblyName assemblyToBuild, String& nameSpace, String& typeName)
   at Versant.LINQPadDriver.VODDynamicDriver.GetSchemaAndBuildAssembly(IConnectionInfo cxInfo, AssemblyName assemblyToBuild, String& nameSpace, String& typeName)
   at LINQPad.SchemaBuilder.GetSchemaAndBuildAssembly(String repositoryData, AssemblyName assemblyToBuild, String& nameSpace, String& typeName, Boolean allowOneToOne, IDictionary`2& sessionData)
   at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
   at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at LINQPad.SchemaBuilder.GetSchemaAndBuildAssembly(String repositoryData, AssemblyName assemblyToBuild, String& nameSpace, String& typeName, Boolean allowOneToOne, IDictionary`2& sessionData)
   at LINQPad.DataContextManager.Runner.UpdateSchema()
   at LINQPad.DataContextManager.Runner.GetDCInfo(SchemaChangeTestMode schemaTestMode)

I'm using the GetAssembliesToAdd override to provide the locations of the DLLs.

//called by driver's overridden method
public IEnumerable<string> GetAssembliesToAdd(string driverFolder)
{
     string vDll = Path.Combine(Environment.GetEnvironmentVariable("VERSANT_ROOT"), "bin", "Versant.Persistence.dll");
     string lpdDll = Path.Combine(driverFolder, "VersantLinqPadDriver.dll"); 
     return new[] { lpdDll, vDll, Props.CustomAssemblyPath }; 
}

static public IEnumerable<string> GetNameSpacesToAdd()
{
     return new[] { "Versant.Persistence" };
}
Other curious tidbit, is the Versant.Persistence.dll needed the fully qualified path even though the dll is in the GAC. I thought that wasn't required?

One final question, why are the GetAssembliesToAdd and GetNamespacesToAdd methods marked obsolete in 4.40? I was reading over your latest DataContextDrivers.doc and didn't see anything about the methods being obsolete.

Thanks for any insight,

Derek
dlaufenberg at versant.com

Comments

  • edited April 2012
    It sounds like you're invoking the CSharpCodeProvider and telling it to compile something that depends on your data context assembly, without telling where that assembly is.

    I would try something like this:
    using (var codeProvider = new CSharpCodeProvider (new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } }))
    {
       string assems = "System.dll System.Core.dll System.Xml.dll "
         + Assembly.GetExecutingAssembly().Location;
    
       var options = new CompilerParameters (assems.Split(), ...);
       var results = codeProvider.CompileAssemblyFromSource (options, code);
       ...
    }
    To answer your other questions, to pull Versant.Persistence.dll out of the GAC, you must specify its fully-qualified name (with the version and so on) rather than its filename, and the reason for GetAssembliesToAdd / GetNamespacesToAdd being obsolete is that there are newer versions of these that accept an IConnectionInfo object. This makes it possible to vary the assemblies/namespaces that you add depending on what the user enters into the connection dialog.
  • edited April 2012
    Thanks Joe. That was indeed it. The split tripped me up for a bit because one of the paths had spaces in it. For anyone who is curious, here the code snipit.

    void BuildAssembly(string customAssemblyPath, string code, AssemblyName name) { string[] codes = { code }; // Use the CSharpCodeProvider to compile the generated code: CompilerResults results; using (CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp", new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } })) { string assems = "System.dll System.Core.dll System.Xml.dll System.Xml.Linq.dll "; var cp = new CompilerParameters(assems.Split(), name.CodeBase, true); //use the Versant.Persistence.DLL, VersantLinqPadDriver, and custom DLL cp.ReferencedAssemblies.Add(typeof(Versant.Persistence.Database).Assembly.Location); cp.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location); cp.ReferencedAssemblies.Add(customAssemblyPath); results = codeProvider.CompileAssemblyFromSource(cp, codes); } if (results.Errors.Count > 0) throw new Exception ("Cannot compile typed context: " + results.Errors[0].ErrorText + " (line " + results.Errors[0].Line + ")"); }

    Cheers,
    Derek

Sign In or Register to comment.