[Estimated Reading Time: 5 minutes]

Yesterday I initially posted that you couldn’t mix Unified Syntax with “traditional” interface and implementation sections. Or what I am now calling Segregated Syntax.

As sometimes happens, shortly after writing what I thought I knew to be true I discovered it wasn’t ! Sorry about that. 🙂

I promised to illustrate the scenario where I found it both possible and useful, and here it is.

As I mentioned, I’m working an ASP.NET MVC/WebApi project using Oxygene.

The project employs ASP.NET Identity with Entity Framework for an auth server component in the project. As part of the implementation I am incorporating OAuth middleware with an ‘api/Account‘ end-point in my REST Api to support auth flows including external logins.

Here’s my AccountController declaration:

interface type AccountController = public class(ApiController) private property Authentication: IAuthenticationManager read Request.GetOwinContext.Authentication; property UserRepo: UserRepository := new UserRepository; readonly; private method GetErrorResult(identityResult: IdentityResult): IHttpActionResult; method ValidateClientAndRedirectUri(request: HttpRequestMessage; var redirectUri: String): String; protected method Dispose(disposing: Boolean); override; public method ExternalLoginAsync(provider: String; error: nullable String := nil): Task<IHttpActionResult>; method RegisterAsync(user: UserModel): Task<IHttpActionResult>; end; implementation // the donkey-work is down here as 'usual'

As you can see, although by no means massive, this is still quite a “busy” controller. The implementation details aren’t really relevant to the example. All you really need to know is that a couple of those methods have quite extensive implementations so to keep things clearer I chose in this case to use interface and implementation sections to keep things organised.

One effect this has (and you could argue this as a Good or a Bad thing I guess) is that any attributes on the method implementations are no longer apparent from / cluttering up (depending on your point of view) the class declaration. Using Unified Syntax any such attributes have to appear in the declaration since there is nowhere else for them to go.

Before we move on though, there are a couple of things worth pointing out for people not familiar with Oxygene, specifically in the declaration of the two properties.

First, the Authentication property:

property Authentication: IAuthenticationManager read Request.GetOwinContext.Authentication;

This demonstrates the use of an expression in the read clause of a property. In traditional Delphi code this would necessitate a separate accessor function. Not so in Oxygene. This has been supported since the very early days of Oxygene (I think as far back as when it was known as Chrome in fact) but in retrospect has a lot in common with the new Unified Syntax now more generally available.

Next up, the UserRepo property:

property UserRepo: UserRepository := new UserRepository; readonly;

Admittedly this isn’t very modern of me. If I was being fashionable I might be using Ninject or some other IoC framework. Then again, given the small size of this auth project, I might not. But that’s a separate discussion.

For now, let’s just focus on this property as written, and in that two things are a bit odd.

The Curious Case of the Read-Only Property That Was Written

First, instead of a read accessor the property is being directly assigned to in the declaration. And secondly, it is also marked readonly.

The result is that I have a UserRepo property which absolutely is read-only as far as the consumers of my controller class are concerned. Without that readonly directive, the property would be read/write.

To make readonly properties useful there has to be an exception that allows the property to be initialised and in Oxygene that includes a declared initialization (as in this case) or an assignment allowed in any ctor of the class. Both approaches will perhaps be familiar to C# developers.

The Delphi equivalent would involve a member variable and a ctor in addition to the property:

// ... private fUserRepo: UserRepository; public property UserRepo: UserRepository read fUserRepo; constructor Create; // with implementation somewhere down below to initialise fUserRepo; // ...

You can of course do effectively the same thing in C#, but there you also have some alternatives. Unfortunately (for C# developers) those alternatives could be something of a minefield since it was decided that the readonly directive can be applied only to member fields not properties.

You could avoid the need for a separate property declaration by using an initialised, readonly field:

public readonly UserRepository UserRepo = new UserRepository;

This is very close to Oxygene‘s read only properties, except that the resulting member is a field, not a property.

It may be a moot difference in the case of read-only fields, but it is still a difference and doing this sets you up nicely for some lengthy debates about whether this constitutes a valid exception to the House Rules rules regarding exposure and naming of member fields as well as landing you in the clutches of code-analysis tools that will castigate you for directly exposing a member field.

To avoid such wrangles you could of course introduce a property so you can push the member field explicitly back into the private sphere where it belongs, accessed by an implicitly read-only public property (with only a getter) keeping your coding standards police off your back and the code analysis tools quiet.

For the purposes of this exercise I am going to expand the indentation of those braces, just to show how “noisy” this really is:

private UserRepository _userRepo = new UserRepository(); readonly; public property UserRepository UserRepo { get { return _userRepo; } };

Nobody would do that in real life ? Au contraire. I had to contend with a class with a number of such read-only properties declared and laid out in precisely this way only today. I’m still feeling a little traumatised by the experience. 🙂

Save for the elimination of the ctor (assuming that a ctor is not needed for other things) this has more than a passing resemblance to the Delphi original; which perhaps isn’t all that surprising remembering that Delphi in many ways directly begat C#.

But, back to the mix-in of Unified and Segregated Syntax.

Mixing Things Up In

As part of the implementation of the ExternalLoginAsync() method, I needed a new class to encapsulate some data pertinent to the external login process. This class would be essentially a POCO albeit adorned with a simple factory method. Significantly, it was to be entirely private to the implementation of the AccountController.

As such I didn’t see the need for a separate unit and decided to place the new class in the implementation section of the existing AccountController unit.

But it bothered me that the quite straight-forward factory method was the only code involved in this class and breaking that out into a separate implementation body (in accordance with Segregated Syntax) irked me in this case.

Fortunately of course, my irk was unfounded and I was able to do this:

interface // .. the AccountController declaration is here .. implementation type ExternalLoginData = class public property LoginProvider: String; property ProviderKey: String; property UserName: String; property ExternalAccessToken: String; class method FromIdentity(identity: ClaimsIdentity): ExternalLoginData; begin // manufacture happens here... end; end; // .. the AccountController implementation is here... end.

A bit of further experimentation lead me to also identify that you can mix-in even within the same class.

So in the case of the AccountController itself I could keep the complex implementation details carefully coralled in the implementation section, but bring some of the trivial scaffolding up into the declaration in the interface section.

The Dispose() method override is a potential candidate for just that:

interface type [Authorize] AccountController = public class(ApiController) private property Authentication: IAuthenticationManager read Request.GetOwinContext.Authentication; property UserRepo: UserRepository := new UserRepository; readonly; private method GetErrorResult(identityResult: IdentityResult): IHttpActionResult; method ValidateClientAndRedirectUri(request: HttpRequestMessage; var redirectUri: String): String; public method ExternalLoginAsync(provider: String; error: nullable String := nil): Task<IHttpActionResult>; method RegisterAsync(user: UserModel): Task<IHttpActionResult>; protected method Dispose(disposing: Boolean); override; begin if disposing then UserRepo.Dispose; end; end; implementation // etc etc, including the method bodies for those not implementing in the Unified Syntax

So there you have it.

Instead of handing down tablets of syntax and strait-jacketing the developer, Oxygene now grants the freedom to use, ignore or (let’s face it) abuse this particular aspect of the syntax in an impressively flexible and intuitive (or at least very natural-feeling) manner.

As I said before, although I was initially skeptical of the very idea of Unified Syntax it has very quickly become one of my favorite features of Oxygene.