Ok, so here goes...
First suppose we have this domain class definition:
public interface IInterceptableClass
{
string FirstName { get; set; }
string LastName { get; }
string GetLastName();
}
public class InterceptableClass : IInterceptableClass
{
public string FirstName { get; set; }
public string LastName { get; private set; }
public InterceptableClass()
{
LastName = "lastname";
}
public string GetLastName()
{
return LastName;
}
}
And suppose you have a simple interceptor behavior defined like so:
internal class SampleInterceptorBehavior : IInterceptionBehavior
{
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
// this invokes the method at the tip of the method chain
var result = getNext()(input, getNext);
// method executed with no exceptions (yay)
if (result.Exception == null)
{
//input.Target
Console.WriteLine($"intercepting: target={input.Target.ToString()}, method={input.MethodBase.Name}");
}
else // boo..!
{
// handle exception here
Console.WriteLine($"error! message={result.Exception?.Message}");
}
return result;
}
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
public bool WillExecute { get { return true; } }
}
You would wire it up via Unity
like this:
static void Main(string[] args)
{
var container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterType<IInterceptableClass, InterceptableClass>(
new Interceptor<TransparentProxyInterceptor>(),
new InterceptionBehavior<SampleInterceptorBehavior>());
var myInstance = container.Resolve<IInterceptableClass>();
// just want to illustrate that privae sets are not supported...
myInstance.FirstName = "firstname";
var lastname = myInstance.GetLastName();
Console.ReadLine();
}
Note that if you don't use Unity to wire up the interception, you would have to do this manually. For one-offs, some devs might prefer it that way, but in practice I've always found that path to be unsustainable, and with multiple intercepts, quite brutal. So always use Unity, if you can.
If you absolutely have to bypass Unity though, here's how you do it:
var manualInstance = Intercept.ThroughProxy<IInterceptableClass>(
new InterceptableClass(), // <-- this could be an already-existing instance as well...
new TransparentProxyInterceptor(),
new IInterceptionBehavior[]
{
new SampleInterceptorBehavior()
});
manualInstance.FirstName = "firstname";
var lastname = manualInstance.GetLastName();