基于复杂模块的使用 ASP.NET MVC 2 在数据库中创建新记录
我有一个非常棘手的问题需要解决,我思考并搜索了很多,并得出了一个结论,我将在下面提到这一点。 问题是我有一个客户想要创建一个基于通用功能的网站,所以让我们称之为模块,所以我的想法是使用 MVC Contrib Portable Areas,这是插入模块的好主意,但我有一个大问题,假设我创建了一个博客模块,该模块将在他想要的新站点中实现,现在一些用户有独特的要求,例如其中一个用户需要在每篇文章中添加图片库,或者在每篇文章中添加参考文献列表。 在正常情况下,这很容易,您只有一个站点可以工作,因此您所要做的就是
- 向博客表中添加一个带有外键的新图库表。
- 重新生成 Linq2SQl 代码并更新模型。
- 将新的表单元素添加到创建、编辑、删除视图中。
- 在控制器中添加逻辑。
由于两个原因,它很复杂而且很麻烦
- 但在我的情况下,如果新功能很酷的话, 客户决定实施它 所有网站,那么我必须重复 为每个站点工作。
- 如果功能是独特的,它将在将来给我带来不一致,
这就是为什么作为解决问题的第一步,我使用可移植区域为每个模块创建插件,现在这肯定会通过为每个新模块拖动 1 个 DLL 或插件,但我这里有一个小问题,
- 因为新的模块或插件是 dll,我怎样才能创建这样一个 我的管理面板中的功能 安装新的插件或找到任何新的 添加模块/插件拖动新的 DLLS 到主要应用程序
- 什么是最好的 练习创建安装 便携式区域内的程序, 比如更新数据库、新路由等。
现在到最大的问题,这是特定于模块插件的:) 让我们收回文章库插件,如果我遵循上面提到的逻辑,将其创建为可移植区域,那么在模块代码中创建一个功能来循环所有已安装的插件并将它们列在 CRUD 中会更容易视图,但由于我隔离了插件并且不想出于上述原因手动更新主模块代码,因此无法对与主模块同步的新插件进行 CRUD 操作,因为没有外键关系,再次因为正如我上面所说,它可能是可选的,所以我想到了以下解决方案,我希望有一个更好的解决方案
首先在安装过程中我将为 Gallery Addon 创建一个表,而不是创建外键关系我将创建一个手动外键,当我使用以下代码创建记录时,将通过在主模块控制器中生成唯一 ID 来填充该外键,然后将其存储在 ViewData 中,并在创建新记录时将其传递给 Addon 控制器,
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();
但这是我的担忧
- 这种方式可行还是简单 愚蠢的。
- 这项技术会吗 生成真正唯一的密钥。
如果我的问题很蹩脚,我感到非常抱歉,但这是最好的提问地点,我认为很多人都希望拥有这样的功能,并希望有人能回答我
I have a very tough problem for me to solve, and I thought and searched alot and came down t one conclusion which I will mention down.
the problem is I have a client that wants to create a websites based on a Common functionality, so let us call it Modules, so what I thought is to use MVC Contrib Portable Areas, which are great ideas to plug Modules, but I have a big problem, let us say I created a Blog module which will be implemented in a new site he want, now some users have unique requirements like one of them needs to add Gallery of pictures to each article, or List of references in each article.
this would be easy in normal situation where you have one site to work on, so all what you have to do is
- add a new gallery table with Foreign key to the Blog table.
- regenerate Linq2SQl code and update the Model.
- add new form elements to the Create, Edit, Delete Views .
- add the logic in the controller.
but in my situation it is complicated and time cumbersome because of 2 reasons
- if the new functionality is cool
and client decide to implement it in
all sites, then I have to repeat the
work for each site. - if the functionality is unique it will create inconsistency for me in future
that is why as first step to solve the problem I used Portable Areas to create Addons for each Module, now this will definitely ease my work by dragging 1 DLL for each new Module or Addon, but I have a little problem here, which
- because the new Module or Addin is a
Dll, how can I create such a
functionality in My Admin panel to
install the new Addon or find any new
added Module/Addon dragged new DLLS
to the Main Application - What is best
practice to create an installation
procedure inside the Portable Area,
like Update the DB, New Routes, etc..
Now to the biggest Problem which is specific to Module Addon :)
let us take back the Article Gallery Addon, if I follow the logic I have mentioned above by creating it as a Portable area, it would be easier to create a functionality in the Module Code to loop through all Installed Addons and list them in the CRUD Views, but because I isolated the Addon and don't want to manually update the Main Module Code for the Reasons Above there will be no way for doing CRUD operations for the new Addons in Sync with the main module because there is no Foreign Key Relation, again because as I said above it may be Optional, so I thought of the following solution which I hope there would be a better one
First in Installation Process I will create a Table for the Gallery Addon, but instead of creating a foreign Key relation I will create a manual Foreign Key which will get populated by Generating a Unique ID in the Main Module Controller when I create record by using the following code then store it in ViewData and just pass it to the Addon Controller when I create the new Record,
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();
but here are my Concerns
- Is this way feasible or just plain
Stupid. - is this technique will
generate a truly unique key.
I am extremely sorry if my question is lame, but this is the best place to ask and I think many people would want to have such a functionality and hope someone will answer me
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为这是一个很好的问题。不久前,我开始使用 MVC1 开发一个 CMS 项目,我想在其中支持插件。我让它工作,以便管理员可以将新的插件程序集放入 bin 文件夹中,下一个应用程序启动时,它将扫描所有程序集以查找 IPlugin (或其他)并加载它们。我将部分视图嵌入到插件程序集中,因此它是独立的。每个插件在放置在页面上时都会被赋予一个唯一的标识符,并且插件的控制器知道如何使用该 ID 来查询其自己的表(存储库)中的数据。主应用程序对插件的架构一无所知。
这里唯一的区别是,听起来您将在同一个数据库上运行多个网站,并且您需要区分每个网站所需的插件实例。我假设在某个地方你有一个键来指示它是哪个网站,可以通过外键使用它来仅选择用户所在页面的该网站的插件。
我不确定这是否是一个答案,我只是在大声思考。希望对讨论有一点帮助。
编辑:为了自动加载插件,我使用 NInject 的功能来扫描 IModule 的程序集。我的IPlugin继承自
Ninject.Modules.INinjectModule
,所有插件都实现IPlugin接口。然后在应用程序启动时,我有以下行:其中内核是 Ninject.IKernel,该行将扫描与该文件模式匹配的任何程序集,因此我可以放入像 Weather.Plugin.dll 这样的程序集。
I think it's a great question. awhile ago I started working on a CMS project using MVC1, where I wanted to support plugins. I had it working so that the admin could drop a new plugin assembly into the bin folder, and next app start, it would scan all assemblies for IPlugin (or whatever) and load them. I embedded the partial views into the plugin assembly so it was all self contained. each plugin was given a unique identifier when it was placed on a page, and the plugin's controller knew how to use that ID to query it's own table (repository) for it's data. the main application didn't know anything about the plugin's schema.
the only difference here is that it sounds like you would have multiple websites running on the same database, and you need to differentiate which instances of the plugin you need for each website. I assume somewhere you've got a key that indicates which website it is, that could be used via foreign key to select only the plugins for that website for the page the user is on.
I'm not sure if this is an answer, I'm sort of just thinking out loud. hopefully it'll help the discussion a little.
EDIT: To automatically load plugins, I used NInject's ability to scan assemblies for IModules. My IPlugin inherits from
Ninject.Modules.INinjectModule
, and all plugins implement the IPlugin interface. Then on app startup, I have the following line:where kernel is a Ninject.IKernel and that line will scan any assembly matching that file pattern, so I could drop in an assembly like Weather.Plugin.dll.