Architecture Question…

In our product, we are extending GoDiagram in our own separate assembly. This is working fine except we recently ran into an issue which raised a question about the use of the internal access modifer in Go and how we should treat them as we extend Go objects. Here’s an example:

The other day, I needed to change the shilt+click behavior implemented inside of GoTool.DoSelect(). I wanted my implementation be exactly like the implication in the base class except for the behavior around shift+click. In theory, I should be able to copy/paste the code from the base class to my override of DoSelect and modify the code to satisfy my requirements.

However, the base class implementation of DoSelect sets a property in GoTool called CurrentObjectWasSelected. The issues is that this property is marked with the internal access modifier. Since my extension is in another assembly, I can’t access this property directly so my implementation cannot be same as Go’s.

My question is really around how Go recommends us to think of or treat internal properties and methods. For example, one might assume from this example:

1) This property is marked internal because extension assemblies shouldn’t modify it. If I were supposed to modify it, it would be marked protected or public.

2) Go is expecting that extensions to its objects are done inside of the Go assembly so that I can access the internal properties/methods as needed.

3) Go is expecting that extension assemblies will be ‘friends’ of the Go assembly via InternalsVisibleTo for the same reason.

To work around the issue I used InternalsVisibleTo. However, are any of this assumptions correct?

Thanks for your help.

  1. we made a mistake on this one?

    I think you’d be hard pressed to find another such issue in all of GoDiagram. I’m not betting you a steak and a beer or anything, I’m just saying I can’t think of another property like this. It was added late in a development cycle to implement the GoText.EditableWhenSelected feature.

    I remember talking about this here in the development group once, but it doesn’t look like it ended up on the todo list. I’ll make sure it gets reviewed before the next release.

I’ve run into just a couple of places where I would have liked to use internal classes/methods. By and large most of the Go is very flexible and easy to extend. Kudos to Northwoods for making it so flexible. The areas I've had trouble with are relatively small, but I do think Will’s question is a good one.

The first one was access to IntersectsLineSegment on GoObject. My previous post for this is here:

I had another issue where I extended the GoToolLinkingNew tool so that when the temporary link is being moved; several additional links are also being moved. I was calling the base implementation of CreateTemporaryPort to add my additional links. That all worked fine, except when I needed to create the real additional links when the connection was made, I wanted to create the real link between the “Target” property of the GoTemporaryPort. In the end, the GoTemporaryPort code was relatively small, so I made my own class that was a copy of it and used my new temporaryPort class and all is well.

The last issue where I ran into something like this was deriving from GoToolDragging. I wanted to override the Start method, but still use the tool. There are two private variables being set in Start: mySelectionHidden and myModalDropped. This made deriving from the tool challenging. The modifications were related to the select behavior in the Start() method. Since these were private and had no properties, I ended up overriding many of the methods in a copy/paste style (yuck).

These are examples where I didn't know the answers to 1 to 3 above. I used approach 4) create copies of the code (my least favorite thing to do … but it is what I did in these cases). I'm thinking that one of those other options might be better than my #4.