5

我有一个非常棘手的问题要解决,我思考和搜索了很多,得出了一个我会提到的结论。问题是我有一个客户想要创建一个基于通用功能的网站,所以我们称之为模块,所以我想使用 MVC Contrib Portable Areas,这是插入模块的好主意,但我有一个大问题,假设我创建了一个博客模块,该模块将在他想要的新站点中实现,现在一些用户有独特的要求,比如其中一个需要为每篇文章添加图片库,或者每篇文章中的引用列表。在正常情况下,如果您有一个站点可以工作,这很容易,所以您所要做的就是

  • 将带有外键的新库表添加到博客表。
  • 重新生成 Linq2SQl 代码并更新模型。
  • 将新的表单元素添加到创建、编辑、删除视图。
  • 在控制器中添加逻辑。

但在我的情况下,由于两个原因,它既复杂又耗时

  • 如果新功能很酷并且客户决定在所有站点中实现它,那么我必须为每个站点重复工作。
  • 如果功能是独一无二的,它将在未来给我造成不一致

这就是为什么作为解决问题的第一步,我使用便携式区域为每个模块创建插件,现在这肯定会通过为每个新模块或插件拖动 1 个 DLL 来简化我的工作,但我在这里有一个小问题,

  • 因为新的模块或插件是一个 Dll,我如何在我的管理面板中创建这样的功能来安装新的插件或找到任何新添加的模块/插件将新的 DLLS 拖到主应用程序
  • 在便携式区域内创建安装过程的最佳实践是什么,例如更新数据库、新路由等。

现在是模块插件特有的最大问题 :) 让我们收回文章库插件,如果我按照上面提到的逻辑将其创建为可移植区域,那么在模块中创建功能会更容易循环遍历所有已安装插件并在 CRUD 视图中列出它们的代码,但是因为我隔离了插件并且不想手动更新主模块代码,原因是上述原因将无法对新插件进行 CRUD 操作与主模块同步,因为没有外键关系,同样因为我上面说它可能是可选的,所以我想到了以下解决方案,我希望会有更好的解决方案

首先在安装过程中,我将为 Gallery Addon 创建一个表,但不是创建外键关系,而是创建一个手动外键,当我使用创建记录时,将通过在主模块控制器中生成唯一 ID 来填充以下代码然后将其存储在 ViewData 中,并在我创建新记录时将其传递给插件控制器,

private  string GenerateId()
 {
  long i = 1;
  foreach (byte b in Guid.NewGuid().ToByteArray())
  {
   i *= ((int)b + 1);
  }
  return string.Format("{0:x}", i - DateTime.Now.Ticks);
 }
ViewData["FK"] = GenerateId();

但这是我的担忧

  • 这种方式可行还是只是简单的愚蠢。
  • 这种技术是否会生成一个真正唯一的密钥。

如果我的问题很蹩脚,我非常抱歉,但这是最好的提问地方,我想很多人都希望有这样的功能,希望有人能回答我

4

1 回答 1

2

我认为这是一个很好的问题。不久前,我开始使用 MVC1 开发一个 CMS 项目,我想在其中支持插件。我让它工作,以便管理员可以将一个新的插件程序集放入 bin 文件夹中,然后下一个应用程序启动,它将扫描所有程序集以查找 IPlugin(或其他)并加载它们。我将部分视图嵌入到插件程序集中,所以它都是自包含的。每个插件在放置在页面上时都会被赋予一个唯一标识符,并且插件的控制器知道如何使用该 ID 来查询它自己的表(存储库)中的数据。主应用程序对插件的架构一无所知。

这里唯一的区别是听起来您将在同一个数据库上运行多个网站,并且您需要区分每个网站需要哪些插件实例。我假设您在某个地方有一个键,该键指示它是哪个网站,可以通过外键使用该键仅为用户所在页面选择该网站的插件。

我不确定这是否是一个答案,我只是在大声思考。希望对讨论有所帮助。

编辑:为了自动加载插件,我使用了 NInject 扫描组件以查找 IModules 的能力。我的 IPlugin 继承自Ninject.Modules.INinjectModule,所有插件都实现了 IPlugin 接口。然后在应用程序启动时,我有以下行:

kernel.Load( "*.Plugin.dll" );

其中 kernel 是 Ninject.IKernel 并且该行将扫描与该文件模式匹配的任何程序集,因此我可以放入像 Weather.Plugin.dll 这样的程序集。

于 2010-07-16T16:32:47.810 回答