Частичные методы в пользовательских модулях Orchard

Мы разработали DSL, чтобы помочь в кодировании пользовательских модулей Orchard. В методе Editor сгенерированного драйвера мы используем частичные методы, чтобы позволить программисту переопределить поведение сгенерированного кода, если это необходимо.

Однако во время выполнения мы получаем исключение, что частичный метод не реализован.

A first chance exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in Microsoft.CSharp.dll

Additional information: 'MyModule.Drivers.CompanyPartDriver' does not contain a definition for 'CustomEditorGet'

В соответствии со спецификацией C# этого не должно быть, поэтому мне интересно, мешает ли здесь динамическая компиляция (или что-то подобное). Обратите внимание, что код компилируется вручную перед запуском и отладкой, поэтому не должно быть никакого кода, который необходимо компилировать во время выполнения.

Этот бит выглядит следующим образом:

public partial class CompanyPartDriver : ContentPartDriver<CompanyPart>
{
   // other code

   partial void CustomEditorGet(CompanyPart part, dynamic shapeHelper, ref DriverResult result);

   protected override DriverResult Editor(CompanyPart part, dynamic shapeHelper)
   {
      DriverResult result;

      if (AdminFilter.IsApplied(HttpContext.Current.Request.RequestContext))
         result = ContentShape("Parts_CompanyAdmin_Edit",
                               () => shapeHelper.EditorTemplate(TemplateName: "Parts/CompanyAdmin",
                                                                Model: part,
                                                                Prefix: Prefix));
      else
         result = ContentShape("Parts_Company_Edit",
                               () => shapeHelper.EditorTemplate(TemplateName: "Parts/Company",
                                                                Model: part,
                                                                Prefix: Prefix));


      CustomEditorGet(part, shapeHelper, ref result);

      return result;
   }

   // other code
}

Добавление реализации метода CustomEditorGet в частичный класс в другом файле, даже если оно пустое, все в порядке. Просто добавление частичного класса без частичного метода impl не исправит это.

Какие-нибудь мысли?

2 ответа

Решение

(Я надеюсь, что кто-то захочет дать более точный ответ.)

Похоже, вы попали в "плохой" коктейль частичных методов и dynamic аргументы.

С partial void метод, где нет "части" partial class обеспечивает реализацию, partial void метод считается "несуществующим" во время компиляции и фактически не реализуется в IL.

С вызовом CustomEditorGet(part, shapeHelper, ref result); где второй аргумент является выражением типа времени компиляции dynamicмы привязываемся к методу, который не существует. Обычно, когда нет dynamic участвует, весь этот вызов / вызов "удаляется" во время компиляции. Но потому что это dynamic выражение, мы должны отложить "привязку" до времени выполнения. "Может быть shapeHelper будет иметь очень "счастливый" тип, который на самом деле находит метод CustomEditorGet вызвать?"Таким образом, вы получаете исключение во время выполнения.

Выглядит для меня как злоупотребление частичными классами, где правильная конструкция является абстрактным методом. Гораздо больше СУХОГО.

Другие вопросы по тегам