即便现在很多软件都是平台化或者Saas化了,但是用户的定制化需求确是永远存在的;如果单独为某些用户再开发一套软件,相信成本也会高出很多。或者说有的为了方便,直接通过硬编码的方式去实现定制化需求,长此以往,我们就可以见到一座“屎山”了。.
根据以上情况,笔者认为可以采用插件式开发(其实也是很传统的方式了,前面写了几篇反射,这里用到的还是反射,反射在c#中的重要性不言而喻),为不同的用户需求提供不同的插件,如此细分下来,业务和代码层面会简介明了很多。但可能也会带来其他问题,比如插件很多会造成维护困难等;不过相对而言的话,我还是认为此种方式比较优秀;
这篇写了一个简单插件式开发功能的实现,首先就是需要提供一个有约束能力的基类,让所有插件在此标准上实现新的逻辑功能。
这个“基类”可以采用接口来进行约束,也可以采用抽象类(我比较偏向这个方式,因为这样可以直接实现一些公用的、基本的操作,而不需要在每个插件都去实现一次)。
项目结构如下:
实现功能:
- 使用插件式开发实现定制化需求
开发环境:
- 开发工具:Visual Studio 2013
- .NET Framework版本:4.5
实现代码:
//主程序
List<Model> List = new List<Model>();
readonly string PlugInPath = Application.StartupPath + "\\PlugIns";
private void Form1_Load(object sender, EventArgs e)
{
LoadPlugIn();
gridPlug.DataSource = new BindingList<Model>(List);
}
private void LoadPlugIn()
{
if (!Directory.Exists(PlugInPath))
{
Directory.CreateDirectory(PlugInPath);
}
string[] files = Directory.GetFiles(PlugInPath);
foreach (string file in files)
{
if (file.ToLower().EndsWith(".dll"))
{
try
{
Assembly assembly = Assembly.LoadFrom(file);
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
if (type.BaseType.FullName == "PlugIn.Base.BaseClass")
{
object obj = assembly.CreateInstance(type.FullName);
string name = type.GetMethod("Name").Invoke(obj, null).ToString();
string desc = type.GetMethod("Desc").Invoke(obj, null).ToString();
string version = type.GetProperty("Version").GetValue(obj).ToString();
List.Add(new Model
{
Name = name,
Desc = desc,
Version = version,
type=type,
Obj = obj
});
}
}
}
catch (Exception ex)
{
throw ex;
}
}
}
}
private void btnOpen_Click(object sender, EventArgs e)
{
Process.Start(PlugInPath);
}
private void btnRun_Click(object sender, EventArgs e)
{
int index=gridPlug.CurrentRow.Index;
object obj = List[index].Obj;
Type type = List[index].type;
object value=type.GetMethod("Run").Invoke(obj, null);
MessageBox.Show(Convert.ToString(value));
}
public class Model
{
public string Name { get; set; }
public string Desc { get; set; }
public string Version { get; set; }
public Type type { get; set; }
public object Obj { get; set; }
}
//基类
public abstract class BaseClass
{
public abstract string Name();
public abstract string Desc();
public abstract string Run();
public string Version
{
get { return "1.0.0"; }
}
}
//插件1
public class One : BaseClass
{
public override string Name()
{
return "第一个插件";
}
public override string Desc()
{
return "计算2+3";
}
public override string Run()
{
return (2 + 3) + "";
}
}
//插件2
public class Two : BaseClass
{
public override string Name()
{
return "第二个插件";
}
public override string Desc()
{
return "输出HelloWord";
}
public override string Run()
{
return "HelloWord";
}
}
实现效果: