Частичные методы в пользовательских модулях 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
вызвать?"Таким образом, вы получаете исключение во время выполнения.
Выглядит для меня как злоупотребление частичными классами, где правильная конструкция является абстрактным методом. Гораздо больше СУХОГО.