none
Load an assembly from a shared location does not work RRS feed

  • Question

  • Hi there,

    I have few websites that are using the same business logic layer which changes quite often. Therefore I would like the business layer assembly to be in a shared location.

    I want to be able to set the location in the config (and not install the dll in the GAC).

    I followed the steps of method 2 in: http://support.microsoft.com/kb/837908/en-us

    my web.config looks like:
    <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
    <assemblyIdentity name="CoreLib.Models" publicKeyToken="864be330c892b525" />
    <codeBase version="1.0.0.0" href="FILE://\..\..\CoreLib\CoreLib.Models\bin\Debug\CoreLib.Models.dll"/>
    </dependentAssembly>
    </assemblyBinding>
    </runtime>

    but it looks like when I build the solution the dll is being picked from the path defined in the codeBase and being copied into the bin. In production environment the dll should only exist in the shared folder and be referred from there, but when I try to achieve this structure and delete the dll from the website bin I am getting:


     

    Could not load file or assembly 'CoreLib.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=864be330c892b525' or one of its dependencies. The system cannot find the file specified.

    When debugging I can see the the assembly code base is file:///d:/webroot/nnzz/App/Web.App/bin/CoreLib.Models.DLL, and not the code base defined in the web.config.

    Also, just to test assembly loading, I added a test method to the dll in the code base location, and kept the old dll in the website bin. Doing that, I got compilation error on the website, that the method was not found, which implies that the dll was picked from the website bin, and not from the location defined in the <codeBase>. Shouldn't the runtime config definition take higher priority?

    Does anyone know how to make it work so the dll will remain in the shared location only? How can several websites use the same dll in a shared location? and how to make sure the correct dll is picked?

    Thanks

    Naomi

     

     













    Thursday, March 24, 2011 12:31 PM

Answers

  • Hi Naomi again,

     

    I think that CLR did that. For better execution efficiency, it will check the version of the assembly. If the version of assembly in local path is correct, CLR will load it. I suggest you update the version of assembly when you have modified it and update the new version to shared path.

     

    Remarks from MSDN document: <codeBase>

    For the runtime to use the <codeBase> setting in a machine configuration file or publisher policy file, the file must also redirect the assembly version. Application configuration files can have a codebase setting without redirecting the assembly version. After determining which assembly version to use, the runtime applies the codebase setting from the file that determines the version. If no codebase is indicated, the runtime probes for the assembly in the usual way.

    If the assembly has a strong name, the codebase setting can be anywhere on the local intranet or the Internet. If the assembly is a private assembly, the codebase setting must be a path relative to the application's directory.

    For assemblies without a strong name, version is ignored and the loader uses the first appearance of <codebase> inside <dependentAssembly>. If there is an entry in the application configuration file that redirects binding to another assembly, the redirection will take precedence even if the assembly version doesnt match the binding request.

     

    Have a nice day!


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Paul Zhou Monday, April 11, 2011 3:08 AM
    Thursday, April 7, 2011 8:35 AM

All replies

  • You can do it using reflection. AppDomain.LoadAssembly or Assembly.Load. There are many ways, but they sims to be a little bit painful.
    Don't forget to mark the correct answer Blog
    Friday, March 25, 2011 2:57 PM
  • Hello NNZZ,

    In Solution explorer, open the 'references' folder under project. Select your dll, right click and click 'Properties'. In properties window, set CopyLocal property to false.

    Please let me know if you still face the same issue.


    Please mark this post as answer if it solved your problem. Happy Programming !!!
    • Marked as answer by Paul Zhou Friday, April 1, 2011 3:34 AM
    • Unmarked as answer by NNZZ Monday, April 4, 2011 9:30 AM
    Friday, March 25, 2011 5:04 PM
  • Hello NNZZ,

    Any updates? Did you try my suggestion?

     


    Please mark this post as answer if it solved your problem. Happy Programming !!!
    Sunday, March 27, 2011 5:42 PM
  • Hi Naomi,

     

    Welcome to the MSDN forum!

     

    Have you tried Adavesh’s suggestion? Does it work on?

    If you follow the steps in the link you posted, app will get the assembly from the location set by tab<codeBase> if the location can be accessed.

     

    Any more concerns, please feel free to let us know.


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, March 28, 2011 12:59 PM
  • Hi there,

    Sorry for my late response - I was away.

    I tried the copyLocal = false and the dll is still being copied to the bin. I even deleted it completely from the references, and as long as I have it in the <codeBase> it is being copied to the bin.

    When I delete it from the bin (after the it is being copied by the build) the websites fails even though the code base points to the right location.

    So it behaves as if the codeBase is for compilation rather then runtime.

    Any ideas?

    Thanks

    Naomi


    Monday, April 4, 2011 9:29 AM
  • I even deleted it completely from the references, and as long as I have it in the <codeBase> it is being copied to the bin.


    Did your application build successfully after you deleted the dll references completely? Because, if you delete the reference, your application should not build.

    Monday, April 4, 2011 11:10 AM
  • yes, it did...but i think it is because I only access this assembly within mvc views - but now I have added the reference back.

    I have change the codeBase path to be absolute and not relative,

    but now I am getting the following error:

    The type 'CoreLib.Models.Website.WebsiteContext' is defined in an assembly that is not referenced. You must add a reference to assembly 'CoreLib.Models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=864be330c892b525'.

    (even though I have added the reference back)


    any ideas?


    Monday, April 4, 2011 2:44 PM
  • You can do it by creating a new appdomain and setting its bin folder to the shared path (but this bin folder can only be relative to your applications bin folder) and then load your assembly in  this new appdomain. Refer the article :http://msdn.microsoft.com/en-us/library/system.appdomain.relativesearchpath(VS.85).aspx.

    But if consumer of your business logic are on different machines/servers then i would suggest expose your business logic as a service (could be web service) to its consumers. By doing that changes to your business logic become transparent to its consumer and you have better managebility of your service.

    If your application are within machine boundaries then i would suggest using GAC.

     


    Vipin Kumar
    Tuesday, April 5, 2011 8:06 AM
  • The thing is all the consumers are myself, this is an internal architecture. I have several MVC applications, and i just wanted to put the logic they share in shared location.

    I hoped I could find a simple solution, like a config entry. I was thinking of using WCF, but it seems too much, where all I want is having applications using shared bin folder in addition to their own.

    About CAG - this will not work in dev environment - as I am using signed assemblies - and all the developers/designers are using the same signature (otherwise it would be to messy when checking in/out)

    So I hoped that configuring codebase in the config will do...

    I have change the following:

    1. changed the codebase to be an absolute path

    2. add the shared assembly to the compilation tag in the config.

    So now if I delete the dll from the bin the sites works as expected and the dll seems to be picked from the shared location.

     

    I still don't understand why even though I set Copy Local = False, the dll is being copied to the bin.

    When I look at the project file, the copy local is a set by a tag <Private> which is highlight as invalid child of <ProjectReference>

     

    <ProjectReference Include="..\..\CoreLib\CoreLib.Models\CoreLib.Models.csproj">
       <Project>{37DBF67A-FA7E-48DD-A0A8-50FA621F9359}</Project>
       <Name>CoreLib.Models</Name>
       <Private>False</Private>
      </ProjectReference>

    Any ideas?

    Thx

    Naomi

     




    Tuesday, April 5, 2011 9:40 AM
  • Hi Naomi again,

     

    I think that CLR did that. For better execution efficiency, it will check the version of the assembly. If the version of assembly in local path is correct, CLR will load it. I suggest you update the version of assembly when you have modified it and update the new version to shared path.

     

    Remarks from MSDN document: <codeBase>

    For the runtime to use the <codeBase> setting in a machine configuration file or publisher policy file, the file must also redirect the assembly version. Application configuration files can have a codebase setting without redirecting the assembly version. After determining which assembly version to use, the runtime applies the codebase setting from the file that determines the version. If no codebase is indicated, the runtime probes for the assembly in the usual way.

    If the assembly has a strong name, the codebase setting can be anywhere on the local intranet or the Internet. If the assembly is a private assembly, the codebase setting must be a path relative to the application's directory.

    For assemblies without a strong name, version is ignored and the loader uses the first appearance of <codebase> inside <dependentAssembly>. If there is an entry in the application configuration file that redirects binding to another assembly, the redirection will take precedence even if the assembly version doesnt match the binding request.

     

    Have a nice day!


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Paul Zhou Monday, April 11, 2011 3:08 AM
    Thursday, April 7, 2011 8:35 AM