Fiia.Net Infrastructure

From EQUIS Lab Wiki

Jump to: navigation, search

Implementation-Level Connectors

Overview

The intent of the supported connector types is to allow Workspace to interact well with existing and traditionally-written C# code. To this end, we allow connections between events, methods and properties whenever there is a reasonable semantic meaning. For example, it makes sense to connect an ICollection<IVillager> to two IVillager objects, but not to an object that does not implement IVillager. Similarly, it makes sense to connect an event to a compatible method, but not to a property of type IVillager.

  • Events and collection properties may be the source for multiple targets.
  • Properties with declared type IInvokable will be made compatible with anything.
  • The special target name "<self>" corresponds to the object itself rather than any of its members.

Algorithm

Warning: Overloaded methods are not yet supported as ports.

A source port name corresponding to:

  • an event with signature S will be treated as a readable member of type ICollection<Delegate<S>>;
  • a property will be treated as a member with appropriate type and accessibility.

A target port name corresponding to:

  • "<self>" will be treated as a readable member of type T;
  • a method with signature S will be treated as a readable member of type Delegate<S>;
  • a property will be treated as a member with appropriate type and accessibility.

The following rules apply on connection, in order:

  • if the source is readable, writable, and assignable from the target type: set the source to the target;
  • if the source is readable, is a collection of type T, and T is assignable from the target type: add the target;
  • if the source is readable, writable, and of type IInvokable: set the source to an invoker of the target;
  • if the source is readable, and is a collection of type T: add an invoker of the target; and
  • if the source is readable, writable, and the target type is IInvokable: set the source to a stub of the target.

A type is interpreted as "a collection of type T" if it implements IEnumerable and provides methods compatible with Add(T) and Remove(T). This identification is based on the behaviour of collection initializers in C# 3.0, which do not depend on the ICollection or ICollection<T> interfaces.

An invoker is a generated object that implements IInvokable and performs native method calls. A stub is a generated object that implements a set of interfaces and generates IInvokable calls from any native method calls to them. Invokers and stubs provide all the interfaces of the typed end of the connection. They do not perform static type checking and impose at least 15x the cost or a direct method call, so should be avoided where possible.

If no member is found that corresponds to a target port name and the target implements IDynamicTargets, the IDynamicTargets.GetTarget(String name) method will be called. If no member is found that corresponds to a source port name and the source implements IDynamicSources, the IDynamicSources.Connect(String name, Object target) method will be called.