Reputation: 6597
I'm building an ASP.NET website that will act as a "framework" and display information about some services that are running on the web server. One of the things that the site needs to do is serve up custom configuration pages for some modules that have been loaded by the service. The modules will all implement a common API, so there is no concern there -- my concern is how can I get configuration pages, which are unique to each module, served up by a common front end?
The pages need to validate user input, handle button clicks, etc. So it's not as simple as having a method on each module:
public string getHTMLConfigPage()
That would only work if the module's config page didn't require user input. In this case, all of the modules will require some form of configuration, at the very least a checkbox indicating "turn on/off"
Here's the ideal use case:
We've already implemented this successfully in C# winforms. The way we did it there was to have each module implement a method public void showConfigDialog(IWin32Window parent);
. That works well for a regular desktop app -- but obviously doesn't help me do anything with the web server.
The only thing that I have thought of so far is to have each module also install some stuff onto the IIS web server, and then just do an iFrame
where the main "framework" page can display the module's page in the frame (or a popup window), but that seems messy in that the module developer has to then include some kind of setup scripts to put stuff into the IIS space...
So - is there a better way to do this, or is the iFrame method the only way?
Systen Details:
EDIT: Additional Details
I have also thought about having the modules place a special ASP.NET DLL in a directory that ASP.NET will probe at runtime. But the root of the problem remains -- how can the DLL provided by module get integrated into the main set of web pages? The main set of web pages have a Site.Master
page that provides some required items (CSS, menu bar, some jQuery addons, etc.). The DLLs from the modules will likely need this information plus a named pipe that the main web pages use to talk back to an underlying windows service we have written.
Upvotes: 1
Views: 1849
Reputation: 4619
Most of what you described is implemented in Orchard CMS. http://orchardproject.net. You might consider looking at their code as an example for how to accomplish this dynamic module loading, or if possible just switching over to Orchard as the framework for your app. It's known as a CMS, but really it's a nice framework to build a .NET app on top of.
They use Autofac for depedency injection, and modules can inject their own Routes, Content, Pages, etc, by implementing interfaces. Orchard's core framework scans those modules for classes that implement specific interfaces, and then call the methods on those interfaces to pull the specific content from the modules. You can enable/disable modules from the command line or from the web interface.
For example I can create a module, and then in there I'll have a class that implements an interface called INavigationProvider
that has methods Orchard uses to get the menu items for the admin dashboard. Then I can implement the IRouteProvider
interface in another class, that tells Orchard about all the routes for my app (both front end and admin dashboard). You can also use MVC conventions for Views/Controllers/Routes. There is support for both Razor and WebForms view engines.
Upvotes: 1
Reputation: 3970
I would suggest:
Upvotes: 0
Reputation: 4803
It sounds like you need a plug-in framework for ASP.NET. You could achieve this by using MEF (Managed Extensibility Framework) which will allow you to put the complex pages and configuration into a plug-in and load it at runtime; or so I believe.
Start by checking out a Code Project article here, and there maybe the MSDN example here.
Upvotes: 3
Reputation: 1058
If you have the different scenarios well defined, I think is not a problem to treat with data from a page in other class or from another embebed project or library. For example, for populate the data in the DropDownList you can do:
Partial Class Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
Dim itemList As List(Of ListItem) = ClassForTheMagic.GetItemsForComboBox(txtBox1.Text, checkBox2.check, ...)
For Each item As ListItem In itemList
DropDownList1.Items.Add(item)
Next
End If
End Sub
End Class
Then, you can have in other file:
Public Class ClassForTheMagic
Public Shared Function GetItemsForComboBox(ByVal txtBox1 As String, ByVal checkBox2 As Boolean, ...) As List(of ListItem)
Dim itemList As New List(Of ListItem)
itemList.Add(New ListItem(txtBox1, "..."))
itemList.Add(New ListItem(checkBox2, "..."))
...
Return itemList
End Function
End Class
ps: sorry for the vb code
Upvotes: 0