Динамически расширяемые возможности приложения?

Я недавно натолкнулся напуть разрабатывать подключаемые модули приложений при использовании ASP.NET MVC3 / 4, и мне понравилась простота этого подхода. В настоящее время мои приложения структурированы следующим образом:

enter image description here

Поэтому любой, кто хочет разработать расширение для моего приложения, следует подходу, описанному выше.руководство и создает расширение, которое остается вAreas папка. Я полагаю, что когда новыйAreas (созданные как новые проекты),.pdb файлы создаются и помещаются вbin каталог. У меня вопрос такой:

How does one distribute the Areas as pluggable modules? How do I change the following code so that when someone drops a new Area into the bin folder, the application automatically picks it up and creates a link? And what should the plugin author do to enable this?

В моем_Layout.cshtml (глобальный общий макет), я делаю следующее для построения ссылок:

<ul>
      <li>@Html.ActionLink("Area1", "Index", "Area1", new { Area = "Area1" }, null)</li>
      <li>@Html.ActionLink("Area2", "Index", "Area2", new { Area = "Area2" }, null)</li>
      <li>@Html.ActionLink("Area3", "Index", "Area3", new { Area = "Area3" }, null)</li>
</ul>

Для простоты предположим, что названия областей уникальны. Любые предложения о том, как это сделать?

 Goran Obradovic18 июн. 2012 г., 11:31
Вы можете проверить мой аналогичный вопрос, так как он может дать некоторую информацию для вас (однако ответов нет):stackoverflow.com/questions/10151566/…
 Legend13 июн. 2012 г., 23:50
@ tere & # x161; ko: Возможно, ты прав. Я удалилmvc пометить, если это то, что вы имели в виду. Спасибо, что указали.

Ответы на вопрос(5)

nopcommerce проект.

Посмотрите на ихГалерея... Модули распространяются в виде пакетов Nuget, содержащих весь проект модуля.

MVCContribпортативные зоны.

Они используют шаблон сообщения / шины приложения для динамического добавления новых виджетов в веб-элементы. MessageHandlers обнаруживаются с помощью отражения, и каждое сообщение передается всем им. Так что в вашем случае автор плагина должен просто реализовать обработчик для стандартного сообщения (например, зарегистрировать ссылку глобального меню).

Ресурсы переносимых областей встроены, поэтому в папку bin можно поместить только одну DLL. Для того, чтобы автоматически подобрать его и использовать в своем приложении, вам нужно будет просмотреть папку bin, скажем, черезFileSystemWatcher и перезапустите ваше приложение (я думаю, что нет другого способа загрузить новый .dll в AppDomain в приложении asp.net).

Вы также можете загружать .dll из других папок, используя функциональность BuildManager в ASP.NET 4. Более полезная информация об этомВот.

 18 июн. 2012 г., 12:25
Нет необходимости добавлять FileSystemWatcher, поскольку веб-приложения ASP.NET автоматически перезапускаются, если изменяется содержимое каталога bin, содержимое web.config или App_code.

take a look at this руководство Я думаю, что это вам очень поможет.

 Legend19 июн. 2012 г., 01:49
+1 Спасибо. В настоящее время проходит через это.
 Legend22 июн. 2012 г., 07:39
Спасибо за урок также! :) @AkosLukacs опубликовал пример проекта на github, если вы заинтересованы.
 Legend19 июн. 2012 г., 01:52
Похоже, единственная проблема заключается в том, что это руководство связано с MVC2, и в настоящее время я использую MVC4. Не уверен, как это повлияет на меня, хотя.
 19 июн. 2012 г., 12:40
На самом деле я не тестировал его в MVC4, но полагаю, что он должен работать. Кстати, спасибо за этот замечательный вопрос :)
Решение Вопроса
How does one distribute the Areas as pluggable modules?

но создавайте отдельные проекты, которые компилируются в отдельные библиотеки DLL. Скопируйте DLL в любое веб-приложение, где вы хотите его использовать. Не забудьте установить все статические файлы как & quot; EmbeddedResource & quot ;.

How do I change the following code so that when someone drops a new Area into the bin folder, the application automatically picks it up and creates a link? And what should the plugin author do to enable this?

Вы можете использовать MvcContrib PortableAreaRegistration & s & quot; Bus & quot; отправлять сообщения, команды из переносной области кому-либо на «шине». Это может быть веб-приложение хостинга или теоретически независимые области, которые могут отправлять сообщения друг другу.

Создал два сырых, но функциональных демо-кода этого кода на github:

MVC3 version:

https://github.com/AkosLukacs/PluggablePortableAreas

MVC4 RC version:

https://github.com/AkosLukacs/PluggablePortableAreasMVC4

Сначала вы определяете сообщение, которое может содержать необходимую вам информацию. Просто POCO, который имеет некоторые свойства (PluggablePortableAreas.Common \ RegisterAreaMessage.cs):

public class RegisterAreaMessage : IEventMessage
{
    public string LinkText { get; private set; }
    public string AreaName { get; private set; }
    public string ControllerName { get; private set; }
    public string ActionName { get; private set; }
    //...
}

Создайте обработчик для этого типа сообщения (PluggablePortableAreas.Common \ RegisterAreaEventHandler.cs):

public class RegisterAreaEventHandler : MessageHandler<RegisterAreaMessage>{}

В этом случае MessageHandler просто добавляет полученные сообщения в статическийConcurrentBag<RegisterAreaMessage>, Вы можете использовать DI, если хотите, но хотите, чтобы все было просто.

Вы можете отправить сообщение из переносной области следующим образом (Areas \ DemoArea1 \ Areas \ Demo1 \ Demo1AreaRegistration.cs):

 //the portable area sends a message to the 'bus'
 bus.Send(new RegisterAreaMessage("Link to the Demo area", AreaName, DefaultController, DefaultAction));

Динамически добавленные ссылки отображаются путем перебора коллекции сообщений (PluggablePortableAreas.Web \ Views \ Shared_Layout.cshtml):

                @foreach(var sor in PluggablePortableAreas.Common.RegisterAreaEventHandler.RegisteredAreas) {
                <li>@Html.ActionLink(sor.LinkText, sor.ActionName, sor.ControllerName, new{Area=sor.AreaName}, null)</li>
                }

Еще одна вещь, о которой нужно позаботиться: используйте & quot; полностью квалифицированную & quot; Названия районов. Если вы не указываете имя области явно, MVC предполагает, что это текущая область. Без областей нет проблем, но вторая будет указывать на"/path_to_your_app/CurrentArea/Home" вместо"/path_to_your_app/Home".

<li>@Html.ActionLink("Home", "Index", "Home", new { Area = "" }, null)</li>
<li>@Html.ActionLink("I don't work from the portable area!", "Index", "Home")</li>
Even one more thing to note!

Сервер разработки в VS чувствует себя немного «ошибочно», иногда переносимая область не загружается. Надежно работает в полном IIS, хотя ...

 21 июн. 2012 г., 02:41
Работает ли в MVC4 RC, код на github - & gt; проверьте обновленный ответ по ссылке.
 Legend22 июн. 2012 г., 07:38
Я очень ценю ваше время в этом вопросе. Большое спасибо за размещение примера репо! Извините, я немного задержался ... Просто передал награду :)
 19 июн. 2012 г., 10:43
MVC4 все еще находится на стадии бета-тестирования, поэтому еще не опробовал его. Я думаю (и надеюсь), что MVCContrib последует, когда он будет окончательным. Или, может быть, будет какая-то поддержка фреймворка, чтобы сделать это без MVCContrib.
 Legend19 июн. 2012 г., 01:49
+1 Спасибо за подробный ответ. Я сейчас пробую это. Последний вопрос, который у меня возникает, - совместим ли MVCContrib с MVC4, потому что это то, что я сейчас использую. Если этот метод не имеет обратной совместимости, я, вероятно, столкнусь с гораздо большей проблемой в будущем. Пожалуйста, дайте мне знать, если у вас есть мнение по этому поводу. Кроме того, я хотел бы услышать, есть ли какие-либо альтернативы MVCContrib или это все делают архитектуру на основе плагинов?

Ваш ответ на вопрос