jonpryor / dblinq2007

Automatically exported from code.google.com/p/dblinq2007
0 stars 0 forks source link

[patch] check to see if provider assembly is already loaded #229

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
This is a patch for a section that was previously marked TODO.

Currently, if add a reference to my provider assembly it gets ignored by
dblinq, which instead searches the working directory for an
appropriately-named DLL (which of course fails if the working directory
isn't the bin directory).

The attached patch will check to see if a correctly-named assembly is
already loaded in the current app domain before doing the file lookup.

Note that if MONO_STRICT is defined, the code for whatever reason insists
on using (DataContext).Assembly instead -- I don't know why so I just left
that part as-is.

Original issue reported on code.google.com by larson.tyler on 7 Apr 2010 at 10:36

Attachments:

GoogleCodeExporter commented 9 years ago
Hm. The latest pull from SVN does things a bit differently in this file, so 
I'll have
to re-examine and revise my patch.

Original comment by larson.tyler on 7 Apr 2010 at 11:13

GoogleCodeExporter commented 9 years ago
OK. Here's a new patch file compatible with the SVN HEAD. I've verified that 
(a) it
works, and (b) it's still necessary.

This solves a common problem with ASP.NET applications throwing an exception 
because
it could not load "DbLinq.MySql", and such: just add a reference to the 
appropriate
assembly and DbLinq won't have to search for it.

Original comment by larson.tyler on 8 Apr 2010 at 12:15

Attachments:

GoogleCodeExporter commented 9 years ago
I don't understand why Assembly.Load() isn't working for you.  I'm also 
surprised 
that this patch works for you.

See also Issue 213, particularly the MSDN docs for Assembly.LoadFrom()

    http://msdn.microsoft.com/en-us/library/1009fa28.aspx

which state that assemblyFile is the filename of an assembly to load.  However, 
in 
DataContext.cs 'assemblyName' will be e.g. "DbLinq.MySql" (NOT 
"DbLinq.MySql.dll"), 
and thus won't be a valid filename.  Result: Assembly.LoadFrom() *should* fail 
with a 
FileNotFoundException.

In short, I don't understand why the current code fails (it should work, at 
least the 
original reporter of issue 213 didn't report that the fix didn't work), and I 
don't 
understand how your patch fixes anything.

Properly configured, Assembly.Load() SHOULD be searching your webapp 'bin' 
directory.  
The current Assembly.Load() code SHOULD be working.

Original comment by jonmpr...@gmail.com on 8 Apr 2010 at 3:16

GoogleCodeExporter commented 9 years ago
By way of testing, I took the NerdDinner source, hacked things horribly to use 
DbLinq instead of System.Data.Linq.  (Lots of 
s/System.Data.Linq/DbLinq.Data.Linq/g in NerdDinner.designer.cs, and anything 
else needed to make it compile.  I didn't care about 
*running* per se, just compiling.)

Place DbLinq.dll and DbLinq.SqlServer.dll files into the webapp 'bin' 
directory, Run, and click the "View All Upcoming Dinners" link, it 
loads.  (Technically I get SqlException because of invalid SQL, but that's not 
the point -- the DataContext has been successfully loaded, 
which is all I care about.)

If I remove DbLinq.SqlServer.dll from the webapp 'bin' directory, run, and 
click the "View All Upcoming Dinnres" link, I get an exception 
from the DataContext constructor:

Could not load file or assembly 'DbLinq.SqlServer' or one of its dependencies. 
The system cannot find the file specified

Stack trace:

[FileNotFoundException: Could not load file or assembly 'DbLinq.SqlServer' or 
one of its dependencies. The system cannot find the file 
specified.]
   System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, 
StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean 
forIntrospection) +0
   System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, 
StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean 
forIntrospection) +43
   System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean 
forIntrospection) +127
   System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean 
forIntrospection) +142
   System.Reflection.Assembly.Load(String assemblyString) +28
   DbLinq.Data.Linq.DataContext.GetVendorInfo(String& connectionString, Assembly& assembly, String& typeName) +483

[ArgumentException: Unable to load the `DbLinq.SqlServer' DbLinq vendor within 
assembly 'SqlServer.dll'.
Parameter name: connectionString]
   DbLinq.Data.Linq.DataContext.GetVendorInfo(String& connectionString, Assembly& assembly, String& typeName) +601
   DbLinq.Data.Linq.DataContext.GetVendor(String& connectionString) +148
   DbLinq.Data.Linq.DataContext..ctor(String fileOrServerOrConnection, MappingSource mapping) +411
   NerdDinner.Models.NerdDinnerDataContext..ctor() in E:\tmp\DbLinqNerdDinner\NerdDinner\Models\NerdDinner.designer.cs:41
   NerdDinner.Models.DinnerRepository..ctor() in E:\tmp\DbLinqNerdDinner\NerdDinner\Models\DinnerRepository.cs:12
   NerdDinner.Controllers.DinnersController..ctor() in E:\tmp\DbLinqNerdDinner\NerdDinner\Controllers\DinnersController.cs:37

[TargetInvocationException: Exception has been thrown by the target of an 
invocation.]
   System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, 
RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck) +0
   System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache) +86
   System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache) +230
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +67
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(Type controllerType) +82

[InvalidOperationException: An error occurred while creating a controller of 
type 'NerdDinner.Controllers.DinnersController'. If the 
controller doesn't have a controller factory, ensure that it has a 
parameterless public constructor.]
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(Type controllerType) +189
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +74
   System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +128
   System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) +57
   System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +7
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

All of which is to say that I believe the current Assembly.Load() behavior is 
(1) correct, and (2) works as expected/designed (i.e. it's 
actually looking for assemblies from the webapp 'bin' directory and loading 
them from there).

Original comment by jonmpr...@gmail.com on 8 Apr 2010 at 5:08

GoogleCodeExporter commented 9 years ago
I did some further testing and it looks like the current SVN version does in 
fact
work -- though for some reason in my initial testing it did not.

But the question remains: should we test to see if the DLL is already loaded? 
If not,
then the TODO: remark can probably be removed.

Original comment by larson.tyler on 9 Apr 2010 at 1:51

GoogleCodeExporter commented 9 years ago
The TODO comment was removed in r1386.

Original comment by jonmpr...@gmail.com on 9 Apr 2010 at 4:15