Michael Sawczyn
Michael Sawczyn

Reputation: 315

Partial methods in Orchard custom modules

We've developed a DSL to help in coding Orchard custom modules. In the generated driver's Editor method, we're using partial methods to allow for the programmer to override the genrated code behavior, if needed.

At runtime, though, we're getting an exception that the partial method isn't implemented.

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'

According to the C# spec, it doesn't have to be, so I'm wondering if the dynamic compilation (or somesuch) is getting in the way here. Note that the code is manually compiled prior to run and debug, so there shouldn't be any code that needs compiled at runtime.

The bit in question is as follows:

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
}

Adding the "CustomEditorGet" method implementation in a partial class in another file, even if empty, all is fine. Just adding the partial class without the partial method impl doesn't fix it.

Any thoughts?

Upvotes: 1

Views: 153

Answers (2)

Bertrand Le Roy
Bertrand Le Roy

Reputation: 17814

Looks to me like a misuse of partial classes where the right construct is an abstract method. Much more DRY.

Upvotes: 0

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 61952

(I hope someone cares to provide a more precise answer.)

It looks like you have hit a "bad" cocktail of partial methods and dynamic arguments.

With the partial void method where no "part" of the partial class supplies an implementation, the partial void method is considered "non-existent" at compile-time, and it is not actually realized in the IL.

With the invocation CustomEditorGet(part, shapeHelper, ref result); where the second argument is an expression of compile-time type dynamic, we "bind" to a method that does not exist. Normally, when no dynamic is involved, this entire call/invocation is "removed" at compile-time. But because this is a dynamic expression, we have to post-pone the "binding" until run-time. "Maybe shapeHelper will prove to have a very 'lucky' type that actually finds a method CustomEditorGet to invoke?" So you get the exception at run-time.

Upvotes: 1

Related Questions