Creating "pluggable" applications in asp.net mvc
I've worked with asp.net MVC and I'm still not very good at it. However, I began to wonder how I can get started building applications that can be "plugged in" or installed on an existing ASP.net MVC site with minimal complexity.
For example, in ASP.net web forms, I developed a kind of blogging application. To install this application I just need to drop the dll in the Bin folder, add a few lines of web.config and then add controls to the aspx pages as needed. No other changes are required.
Now I am working with MVC and I have come across partial views that replace custom webform elements in some way. However, it seems you still need to pass the partial view data from the controller, and this is at a higher level than the page. I will need to change the controller code to install the application.
I am sure I am thinking about this with the wrong thinking. Is there a way to create asp.net mvc apps that can be easily plugged into an existing website?
a source to share
I did quite a bit of work like this and I got pretty much all the information I started getting started here:
http://www.codeproject.com/KB/cs/pluginsincsharp.aspx
My biggest project using plugins is an audio processing application.
General idea:
You create an interface for each of the plugin types you need in a separate, redistributable, signed DLL. Here's a sample interface:
/// <summary>
/// Describes an audio reader.
/// </summary>
public interface IReader : IPlugin
{
/// <summary>
/// Fired by the reader to update the UI on long operations.
/// </summary>
event EventHandler<ProgressChangedEventArgs> ProgressChanged;
/// <summary>
/// Gets a list of of MIME types the reader supports.
/// </summary>
ReadOnlyCollection<string> TypesSupported { get; }
/// <summary>
/// Loads a SampleSet from the given input stream.
/// </summary>
/// <param name="inStream">The stream to read the</param>
/// <returns>A SampleSet read from the stream.</returns>
SampleSet Load(Stream inStream);
}
Then, in your plugin dll, you implement a class with an interface:
public sealed class WavReader : IReader
{
...
}
Then you load the DLL using reflection:
private void LoadPlugins(string applicationPath)
{
if (!Directory.Exists(applicationPath))
throw new ArgumentException("The path passed to LoadPlugins was not found.", "applicationPath");
List<IPluginFactory> factoriesList = new List<IPluginFactory>();
List<IReader> readersList = new List<IReader>();
foreach (string assemblyFilename in Directory.GetFiles(applicationPath, "*.plugin"))
{
Assembly moduleAssembly = Assembly.LoadFile(Path.GetFullPath(assemblyFilename));
foreach (Type type in moduleAssembly.GetTypes())
{
IPluginFactory instance = null;
if (type.GetInterface("IPluginFactory") != null)
instance = (IPluginFactory)Activator.CreateInstance(type);
if (instance != null)
{
factoriesList.Add(instance);
switch (instance.PluginType)
{
case PluginType.Reader:
readersList.Add((IReader)instance.Create());
break;
}
}
}
}
this.readers = readersList.AsReadOnly();
}
And BAM you have your plugins!
a source to share