Skip to content

Instantly share code, notes, and snippets.

@orient-man
Created November 16, 2012 13:46
Show Gist options
  • Save orient-man/4087483 to your computer and use it in GitHub Desktop.
Save orient-man/4087483 to your computer and use it in GitHub Desktop.
How to write interceptor for iterator?
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Castle.DynamicProxy;
using NUnit.Framework;
namespace MyApplication.Tests
{
[TestFixture]
public class ProxyAndEnumerable
{
[Test]
public void ConnectionClosedByProxy()
{
// arrange
var service = new MyService();
var proxy = new ProxyGenerator()
.CreateInterfaceProxyWithTarget<IMyService>(
service, new CloseConnectionInterceptor());
// act
proxy.GetList();
// assert
Assert.IsFalse(service.IsConnectionOpen);
}
[Test]
public void IteratorLeavesOpenConnection()
{
// arrange
var service = new MyService();
var proxy = new ProxyGenerator()
.CreateInterfaceProxyWithTarget<IMyService>(
service, new CloseConnectionInterceptor());
// act
proxy.GetEnumerable().ToList();
// assert
Assert.IsTrue(service.IsConnectionOpen);
}
class CloseConnectionInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
try
{
invocation.Proceed();
}
finally
{
var hasConnection = invocation.InvocationTarget as IHasConnection;
if (hasConnection.IsConnectionOpen)
{
hasConnection.Connection.Dispose();
hasConnection.Connection = null;
}
}
}
}
interface IHasConnection
{
bool IsConnectionOpen { get; }
Connection Connection { get; set; }
}
public interface IMyService
{
IEnumerable<int> GetEnumerable();
IList<int> GetList();
}
class Connection : IDisposable
{
public bool IsDisposed { get; set; }
public void DoSomething() { }
public void Dispose()
{
IsDisposed = true;
Debug.WriteLine("Connection closed");
}
}
class MyService : IMyService, IHasConnection
{
private Connection _connection = null;
public bool IsConnectionOpen { get { return _connection != null; } }
public Connection Connection
{
get
{
if (!IsConnectionOpen)
_connection = new Connection();
return _connection;
}
set { _connection = value; }
}
public IEnumerable<int> GetEnumerable()
{
for (int i = 0; i < 10; i++)
{
// simulating getting results from database
Connection.DoSomething();
yield return i;
}
}
public IList<int> GetList()
{
return GetEnumerable().ToList();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment