If the reader is familiar with Paint.Net, you will notice that we cannot really write a functional AddIn without referencing Paint.Net’s library. There are data types that are only available in Paint.Net. Many CLR AddIn adopters will soon come up with the same questions how to use data types in the Host without referencing the Host (for versioning reasons). The answer is simple “CONTRACT”. Contract is the isolation boundary that calls can flow in and out. Types in Contract can be passed from Host to AddIn or vice versa. The Contract assembly should have very clearly defined for both sides to function correctly.


Here is a list of things that could be used in the contract.

  • Other IContract
  • Serializable value types defined in the contract assembly
  • Common serializable value types in mscorlib (Not 100% guaranteed yet, don’t quote on me)
  • Sealed serilizable reference types in the mscorlib (Not 100% guaranteed yet, don’t quote on me)
  • AddInToken
  • Arrays of above items


To enable Paint.Net support AddIn model, we need to define new Contracts. The code will look like this.



namespace PaintDotNetAddInContract



    public interface IPDNEffectContract : IContract


        void Render(IAddInRenderArgsContract dstArgs, IAddInRenderArgsContract srcArgs,

            Rectangle[] rois, int startIndex, int length);



    public interface IAddInRenderArgsContract : IContract


        IAddInSurfaceContract GetSurface();



    public interface IAddInSurfaceContract : IContract


        int GetWidth();

        int GetHeight();

        IAddInColorBgraContract GetPointAddress(int x, int y);



    public interface IAddInColorBgraContract : IContract


        byte GetIntensityByte();

        byte GetR();

        byte GetG();

        byte GetB();

        byte GetA();

        IAddInColorBgraContract Next();

        IAddInColorBgraContract FromBgra(byte b, byte g, byte r, byte a);




This is not a complete contract definition. The more APIs that the AddIn side need to use, the more contracts and methods we need to expose in the contract assembly. With the contract defined we can route the calls from Host to AddIn through adapters.


Next topic will be about data type adapters.