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?
Note:
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:
Dashboard.exe
- App.Config contains connectionstring
- References SharpMap
- References Domain.Dll
- Contains MapWidget
Domain.dll
- Contains DomainModel and Services
- Uses Entity Model for persistance
- App.config contains connectionstring, entity framework config section and entity framework connection factory
So my questions are:
- Why is it happening?
- What can I do to stop it? (If not, is there a better place then Program.cs for the hacky code)
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:
and it gave me exact exception as you had. After changing it to
it worked just fine. In my case I used
new Map()
instead ofnew MapWidget()
because it is a winforms application.TLDR: think of it as an hack, which performs initialization