tags:

views:

347

answers:

4

We’re developing a web-based application that allows administrators to upload plug-ins. All plug-ins are stored in a special folder outside the app root (say, C:\Plugins) and are dynamically loaded via Assembly.LoadFrom(). This works just fine for the most part: WebControls in the plug-ins are instantiated and loaded, custom classes function as expected, etc.

We’re using a custom VirtualPathProvider to get resources out of these plug-ins. So, to get an embedded ASPX file, you’d simply do like, “/MySite/embeddedResource/?Assembly=MyPlugin&Resource=MyPage.aspx”. And that works fine, too: the embedded ASPX file compiles and is served up like a normal page.

The problem, however, comes in when an embedded .aspx file (inside of a dynamically loaded plugin) references a class inside that same plug-in assembly. We get compilation errors like, “cannot find type or assembly MyPlugin.” This is odd because, clearly, it’s pulling the .aspx file out of MyPlugin; so how can it not find it?

So, I’m hoping you can help me out with this. The plugin would look like this:

MyPlugin.dll:

  • InternalHelperClass.cs
  • MyPage.aspx (resource with no .cs file)

When MyPage.aspx contains something like, “<%= InternalHelperClass.WriteHelloWorld() %>”, the compilation fails.

How can we get this to work?

UPDATE:

We have tried using fully qualified names. No difference. It is impossible to step through - it is a compilation error when you go to the aspx page. Namespaces would not be an issue in this case (since it was from an external plugin dll)

UPDATE2:

Joel, I think you are onto something. Unfortunately, editing the web.config to include these assemblies isn't part of the design. Basically, we want the plugins to be completely dynamic - drop them in a folder, restart the app, and be ready to go.

A: 

Have you tried fully-qualifying the namespace for the helper class? Is it public? Is it in the same assembly? Perhaps it's in another assembly that has to be loaded as well.

Try stepping into the code and examining the type of InternalHelperClass. The newer "website" methods of compilation often add namespaces that you were not expecting. E.G. the class for a web page has the namespace ASP.MyWebPage. And sometimes namespaces are added based on which folder they reside in.

alord1689
A: 

I've never tried to do this, but I suspect that your ASPX page, though it is loaded from your plugin assembly, is being compiled in an ASP.NET environment that has no reference to your plugin assembly - which would explain why the fully qualified name doesn't work.

Have you tried adding a reference to MyPlugin.dll to the compilation/assemblies tag in your web.config file?

Joel Mueller
+3  A: 

Assembly.LoadFrom is dynamic (late bound) which means the type is not included during compilation time therefore references to its contained classes are invalid. You need to specifically reference the assembly so its included as part of the compilation of the *.aspx class.

You may find some of the source code here helpful, and I recommend giving the Managed Extensibility Framework a go because it may have already solved this issue.

Update: I have found what I think is the answer to your problem. While this won't work in an ASP.NET 1.1 project, it would for 2.0+. They have restructured the building pipeline to use a BuildProvider which can be specified in the configuration file (web.config). Though you have to write your own build provider, you can make one that automatically references all the assemblies in the Plugins folder prior to compilation. Here's information on the configuration and here's what you need to subclass to do it.

Here's an out of date copy of the source code for Mono's PageBuildProvider, you'll need to check the latest implementation for ASP.NET from MS's shared source, copy it, and extend it with your custom assembly reference because the class is unfortunately sealed (but it doesn't look terribly complex).

cfeduke
A: 

Any luck with this? I'm trying to get something similar to work.

Inferis