Since Automation Platform V3.4 there are more restrictive checks for the installation of plug-in components. Some customers stumbled over those checks, as their existing plug-in implementations violated some rules. However, the rules have always been existing since the very beginning of Automation Platform, and the checks have now been introduced to avoid development mistakes that can be very severe in the future. This article summarizes which kinds of compile time references are allowed and the reasons why.

Component types

There are three kinds of components in the Automation Platform:

  • Plug-in components: Weak named, side-by-side installation of multiple versions in the PlugIns folder structure.
  • Interface components: Weak named, only the newest version is present in the Common folder. (Remember: As interfaces must remain absolutely compatible through the time, the newest version always "contains" all previous versions.)
  • GAC components: Strong named, side-by-side installation in the global assembly cache.

Compile time reference overview

The following matrix shows all combinations of compile time references and whether each of them is allowed or not. The number in parentheses referes to the subsequent section where a rationale is given.

...references a plug-in component...references an interface component...references a GAC component
A plug-in component...
Prohibited (1)
Permitted
Permitted
An interface component...
Prohibited (2)testcode
Permitted
Prohibited (3)
A GAC component...
Prohibited (4)
Prohibited (5)
Permitted

Rationale

(1) A plug-in component referencing a plug-in component is prohibited

This is essential for the versioning concept. Two plug-ins can only interact with each other in a version-independent way if this interaction is done by one or more intermediate interface components. If there is no need of version-independency, then there is also no reason of having two different plug-in components - the functionality could as well be implemented in a single plug-in component.

(2) An interface component referencing a plug-in component is prohibited

Interface components should not contain any declarations that are implementation specific, so there is no need for having that kind of reference. Consider moving the necessary declarations from the plug-in to the interface component, and make them as less implementation-dependent as possible.

(3) An interface component referencing a GAC component is prohibited

This is the combination that causes the most confusion. Violating this rule can be very serious during future development, and even the CoDeSys development teams has made this mistake a few times, always with great efforts afterwards to get things running again. To understand the essentials behind that rule, consider the following scenario:

GAC component

Compile time references:
irrelevant

Code Snippet:
public class GACType { }

Interface component

Compile time references:
To the GAC component

Code Snippet:
public interface ISample { void MyMethod(GACType arg); }

Plug-in component A

Compile time references:
To the GAC component
To the interface component

Code Snippet:
class SampleImpl : ISample { void MyMethod(GACType arg) { } }

Plug-in component B

Compile time references:
To the GAC component
To the interface component

Code Snippet:
void DoSomething(ISample sample) { GACType arg = new GACType(); sample.MyMethod(arg); }

All components will compile fine, no matter which exact version of the GAC component is referenced. If one of the components changes the reference of the GAC component to another version, everything remains correct at compile time. However, there will be type cast exceptions during runtime because an instance of GACType[version 1] cannot be assigned to a variable or a parameter of GACType[version 2], even if the type layout is completely identical. That's .NET.

Another issue is that if you change the reference within the interface component, then you suddenly have completely incompatible interfaces because MyMethod(GACType[version 1]) is not compatible to MyMethod(GACType[version 2]). However, it is an essential rule that all interfaces in Automation Platform remain compatible forever once released.

There is one exception though: References to .NET runtime assemblies (i.e. assemblies with the System namespace) are allowed to be referenced. .NET has got special type resolution algorithms for that scenario.

(4) A GAC component referencing a plug-in component is prohibited

This combination will simply not compile because a strong-named assembly must not have references to any weak-named assemblies.

(5) A GAC component referencing an interface component is prohibited

This combination will simply not compile because a strong-named assembly must not have references to any weak-named assemblies.