I am using sharp map inside a custom "map widget" component. To populate the map, I want to use the entity framework, which is inside a seperate DLL. This works fine if I create a map, and then get the data.
public void loadMap() {
var map = new MapWidget(); // Create a new widget which internally uses SharpMap
map.AddCountriesLayer(); // Load the map background from .shp file
var data = new IPService.GetPointsForMap(); // Gets IP address from entity framework, inside "domain.dll"
map.AddDots(data); // Add dots
}
However, if I get the data first, and then make the map, things break:
public void loadMap() {
var data = new IPService.GetPointsForMap(); // Accessing entity framework before sharpmap
var map = new MapWidget();
map.AddCountriesLayer();
map.AddDots(data);
}
results in
System.NotSupportedException "The invoked member is not supported in a dynamic assembly."
at System.Reflection.Emit.InternalAssemblyBuilder.GetExportedTypes()
at GeoAPI.GeometryServiceProvider.ReflectInstance()
at GeoAPI.GeometryServiceProvider.get_Instance()
at SharpMap.Data.Providers.ShapeFile.set_SRID(Int32 value) in C:\dev\DLLs\SharpMap Source\Trunk\SharpMap\Data\Providers\ShapeFile.cs:line 859
at SharpMap.Data.Providers.ShapeFile.ParseProjection() in C:\dev\DLLs\SharpMap Source\Trunk\SharpMap\Data\Providers\ShapeFile.cs:line 978
at SharpMap.Data.Providers.ShapeFile..ctor(String filename, Boolean fileBasedIndex) in C:\dev\DLLs\SharpMap Source\Trunk\SharpMap\Data\Providers\ShapeFile.cs:line 302
at Dashboard.Widgets.MapWidget.AddCountriesLayer() in c:\dev\Dashboard\v1\Dashboard\Classes\Widgets\Generic\MapWidget.cs:line 86
What the heck is going on here? Why would using the entity framework first break it?
To fix this issue, I added this to the program.cs, to force the widget to be loaded first.
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Hack to force SharpMap to register before entity framework
var widget = new Widgets.MapWidget();
widget.Update();
Application.Run(new DashboardForm());
}
However, I don't like it - it seems pretty fragile and I don't like "coding by coincidence". Is there anything I can do to fix it?
I found this blog post: http://elegantcode.com/2010/01/28/the-entity-framework-and-the-the-invoked-member-is-not-supported-in-a-dynamic-assembly-exception/ I added the domain assembly to the connectionString
My project structure is this:
So my questions are:
Thanks for reading, please ask me to clarify if I haven't been clear.
I had a very similar problem, but I'm not using Entity Framework (I'm using NHibernate instead), so, I've figured out that this may not be a proxy-object problem after all.
I also dislike "coding by coincidence", but I assume that by calling new MapWidget()
, some initialization related to GeoApi is performed internally - as GeoApi is used by SharpMap internally.
In my case, I was not using the map directly, I was simply inserting some geo data in my database using NHibernate and I was getting exact same stack trace, so I figured that might be the same problem.
As much as I hate it, I had something like this:
// my object to be persisted using NHibernate
var myObj = new MyObj();
// add polygon of type GeoAPI.Geometries.IGeometry
myObj.CoveredArea = myGeoFactory.CreatePolygonArea(/* ... */);
// use NHibernate to save my obj
sessioNScope.Save(myObj); // <- throws NotSupportedException here
and it gave me exact exception as you had. After changing it to
// Ignore this line: hack to initialize GeoApi
new Map();
// my object to be persisted using NHibernate
var myObj = new MyObj();
// add polygon of type GeoAPI.Geometries.IGeometry
myObj.CoveredArea = myGeoFactory.CreatePolygonArea(/* ... */);
// use NHibernate to save my obj
sessioNScope.Save(myObj);
it worked just fine. In my case I used new Map()
instead of new MapWidget()
because it is a winforms application.
TLDR: think of it as an hack, which performs initialization