New Posts New Posts RSS Feed: EntityServerException when querying EntityManager from our own MEF'ed assembly
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

EntityServerException when querying EntityManager from our own MEF'ed assembly

 Post Reply Post Reply
Author
akukucka View Drop Down
Newbie
Newbie
Avatar

Joined: 22-Jul-2010
Location: Rochester, NY
Posts: 11
Post Options Post Options   Quote akukucka Quote  Post ReplyReply Direct Link To This Post Topic: EntityServerException when querying EntityManager from our own MEF'ed assembly
    Posted: 21-Feb-2012 at 2:00pm
First and foremost, we're using DevForce 2010 version 6.0.8.0.

We've created an application that splits functionality across multiple assemblies that are MEF'ed in at app start up.

We're having an issue querying a DevForce BOS from within code in one of these MEF'ed assemblies.  We can do it from the startup project, but when querying the BOS from code within one of our MEF'ed assemblies we get:

There was an error while trying to serialize parameter http://ideablade.com/EntityModel:entityQuerySurrogate. The InnerException message was 'Type 'IdeaBlade.EntityModel.EntityQueryProxy`1[[OUR_CUSTOM_TYPE, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' with data contract name 'EntityQueryProxyOfOURTYPEcFdpr7Ik:http://ideablade.com/EntityModel' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'.  Please see InnerException for more details.

We should be able to query our BOS from MEF'ed assemblies, right?

Thanks!

Adam
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 21-Feb-2012 at 4:08pm
You should be able to query your server from MEF'ed assemblies, but you also have to make sure DevForce knows what you've dynamically loaded.  There are a few ways to do this, here's more info - http://drc.ideablade.com/xwiki/bin/view/Documentation/on-demand-discovery.
Back to Top
akukucka View Drop Down
Newbie
Newbie
Avatar

Joined: 22-Jul-2010
Location: Rochester, NY
Posts: 11
Post Options Post Options   Quote akukucka Quote  Post ReplyReply Direct Link To This Post Posted: 22-Feb-2012 at 5:53am
Ah!  I forgot to mention that we're not using Silverlight; our client application is an XBAP.  I don't think I have the option to add catalogs to the CompositionHost when not using Silverlight (or I've missed it completely).
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 22-Feb-2012 at 9:20am
We just added the ability to add catalogs to the CompositionHost for non-SL applications in the 6.1.6 bits under development now.  This release will be in early March.
Back to Top
dpollot44 View Drop Down
Newbie
Newbie
Avatar

Joined: 13-Jan-2010
Location: Rochester NY
Posts: 24
Post Options Post Options   Quote dpollot44 Quote  Post ReplyReply Direct Link To This Post Posted: 03-Mar-2012 at 8:19am
We're now using 6.1.6.
I have the following code within a class in an assembly that will be MEF'd into a shell application (along with a MEF'd in domain model assembly):

IdeaBlade.EntityModel.TransactionSettings.Default =
new IdeaBlade.EntityModel.TransactionSettings(System.Transactions.IsolationLevel.ReadCommitted, new TimeSpan(0, 1, 0), false);

IdeaBladeConfig.ConfigFileLocation = @"\...\bla\someconfiglocation";
IdeaBlade.Core.Composition.CompositionHost.SearchFolders.Clear();
IdeaBlade.Core.Composition.CompositionHost.SearchFolders.Add(@"\...\some plugin folder");
IdeaBlade.Core.Composition.CompositionHost.SearchPatterns.Clear();
IdeaBlade.Core.Composition.CompositionHost.SearchPatterns.Add("DomainModelAssemblyName.dll");

AssemblyCatalog catalog = new AssemblyCatalog(assembly: Assembly.Load("DomainModelAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"));
IdeaBlade.Core.Composition.CompositionHost.Add(catalog: catalog);
DomainAssembly.EntityManager em = new DomainAssembly.EntityManager();

var entity = em.SomeEntitySet.Where(e => e.Id.Trim() == "someid").FirstOrDefault();
var prop = entity.SomePropery;

I get the following exception (thrown at the line in red)

Type 'IdeaBlade.EntityModel.EntityQueryProxy`1[[DomainModelAssembly.SomeEntitySet, DomainModelAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' is not known to the serializer. The following probe assemblies were found during initialization: DomainModelAssembly.  Make sure that the assemblies holding your entity model and other known types are in this list.  Check that your CompositionHost.SearchPatterns are correct.  Also see the debug log to check for assembly load errors.

I've changed the names of the assemblies/types to protect the innocent, but you get the idea.  The exception is telling me that it's found my domain model assembly, and yet I get an exception nonetheless.

Is there something we're missing??
Back to Top
kimj View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 09-May-2007
Posts: 1391
Post Options Post Options   Quote kimj Quote  Post ReplyReply Direct Link To This Post Posted: 05-Mar-2012 at 2:42pm
It looks like the problem is with the plugin folder.  The AssemblyCatalog is loaded correctly, and the CompositionHost "recomposes", but later logic which is looking at types and assemblies is trying to re-load the assembly in question and not finding it in the path.  You'll probably also see an assembly load error in the debug log for this assembly.
 
We'll get this fixed in the next release, but right now the workaround would be to modify the probing path for the AppDomain, or to copy the assembly into the exe folder and then load the assembly and AssemblyCatalog.  In testing I used the deprecated (but still working) AppDomain.CurrentDomain.AppendPrivatePath method to add the plugins folder to get this working.
 
Also, the various SearchFolders/SearchPatterns stuff is only needed once at application startup, and is ignored after that.
 
 
Back to Top
dpollot44 View Drop Down
Newbie
Newbie
Avatar

Joined: 13-Jan-2010
Location: Rochester NY
Posts: 24
Post Options Post Options   Quote dpollot44 Quote  Post ReplyReply Direct Link To This Post Posted: 06-Mar-2012 at 6:29am
For those having the same problem:
In my bootstrapper I played around a bit with how we're loading our plugins.

protected override IEnumerable<System.Reflection.Assembly> SelectAssemblies()
{
// this NEEDS to be here yo
AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(App.CurrentApp.CurrentDomain_AssemblyLoad);

#if IsDebug
            var extensionsPath = ConfigurationManager.AppSettings["debugBinPath"];
#else
var extensionsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), ConfigurationManager.AppSettings["binPath"]);

// Download assemblies from the server!!
SyncExtensions(extensionsPath);
#endif

            if (!Directory.Exists(extensionsPath))
Directory.CreateDirectory(extensionsPath);

            var assemblyFilenames = Directory.GetFiles(extensionsPath, "*.dll");
var files = assemblyFilenames.Select(af => new FileInfo(af));
files.ToList().ForEach(fi => {
string destFileName = string.Format("{0}{1}", AppDomain.CurrentDomain.BaseDirectory, fi.Name);
if(File.Exists(destFileName))
File.Delete(destFileName);
File.Copy(sourceFileName: fi.FullName, destFileName: destFileName);
});

var assemblies = files.Select(f => Assembly.LoadFrom(string.Format("{0}{1}", AppDomain.CurrentDomain.BaseDirectory, f.Name)))
.Union(new Assembly[] { Assembly.GetExecutingAssembly() })
.Union(base.SelectAssemblies());
return assemblies;
}

I had tried manually copying the files into the execution path before start up, but that didn't work.  This does however.
Hopefully this will help someone.

Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down