Skip to content

Latest commit

 

History

History
128 lines (102 loc) · 3.21 KB

README.md

File metadata and controls

128 lines (102 loc) · 3.21 KB

ProxyInterfaceGenerator

This project uses Source Generation to generate an interface and a Proxy class for classes. This makes it possible to wrap external classes which do not have an interface, in a Proxy class which makes it easier to Mock and use DI.

It supports:

  • properties
  • methods
  • events
  • implicit and explicit operators

NuGet

NuGet Badge

Usage

Given: an external existing class which does not implement an interface

public sealed class Person
{
    public string Name { get; set; }

    public string HelloWorld(string name)
    {
        return $"Hello {name} !";
    }
}

Create a partial interface

And annotate this with ProxyInterfaceGenerator.Proxy[...] and with the Type which needs to be wrapped:

[ProxyInterfaceGenerator.Proxy(typeof(Person))]
public partial interface IPerson
{
}

ProxyBaseClasses

In case also want to proxy the properties/methods/events from the base class(es), use this:

[ProxyInterfaceGenerator.Proxy(typeof(Person), true)] // 👈 Provide `true` as second parameter.
public partial interface IPerson
{
}

ProxyClassAccessibility

By default, the generated Proxy class is public. If you want to create the Proxy class as internal, use the following:

[ProxyInterfaceGenerator.Proxy(typeof(Person), ProxyClassAccessibility.Internal)] // 👈 Provide `ProxyClassAccessibility.Internal` as second parameter.
public partial interface IPerson
{
}

When the code is compiled, this source generator creates the following

1️⃣ An additional partial interface

Which defines the same properties and methods as in the external class.

public partial interface IPerson
{
    string Name { get; set; }

    string HelloWorld(string name);
}

2️⃣ A Proxy class

Which takes the external class in the constructor and wraps all public properties, events and methods.

// ⭐
public class PersonProxy : IPerson
{
    public Person _Instance { get; }

    public PersonProxy(Person instance)
    {
        _Instance = instance;
    }

    public string Name { get => _Instance.Name; set => _Instance.Name = value; }

    public string HelloWorld(string name)
    {
        string name_ = name;
        var result_19479959 = _Instance.HelloWorld(name_);
        return result_19479959;
    }
}

⭐ By default the accessibility from the generated Proxy class is public.

3️⃣ Use it

IPerson p = new PersonProxy(new Person());
p.Name = "test";
p.HelloWorld("stef");

Extra functionality

Ignore members

You can ignore members by adding a property to the membersToIgnore string array.

Example when you want to ignore the Postcode property:

[Proxy(typeof(Address), ["Postcode"])]
public partial interface IAddress
{
}

Note that's also possible to use wildcard matching to ignore multiple members at once.

[Proxy(typeof(Address), ["Post*"])]
public partial interface IAddress
{
}

References