Returning more than one thing from a method in C#

Wanting to return more than one thing from a method is a pretty common scenario. For example, a response and how long it took to retrieve it.

Like anything, there’s more than one way to go about this. You could use an out (or ref) parameter:

public void DoIt()
{
    TimeSpan duration;
    var response = GetResponse(out duration);
    // do something with response & duration
}

private string GetResponse(out TimeSpan duration)
{
    var stopwatch = Stopwatch.StartNew();
    var response = ...;
    stopwatch.Stop();
    duration = stopwatch.Elapsed;
    return response;
}

Or return a (private nested) class, or struct:

public void DoIt()
{
    var result = GetResponse();
    // do something with result.Response & result.Duration
}

private Result GetResponse()
{
    var stopwatch = Stopwatch.StartNew();
    var response = ...;
    stopwatch.Stop();
    return new Result 
    {
        Response = response,
        Duration = stopwatch.Elapsed
    };
}

private class Result
{
    public string Response { get; set; }
    public TimeSpan Duration { get; set; }
}

But .NET 4.0 gives us one more option, an anonymous type:

public void DoIt()
{
    var result = GetResponse();
    // do something with result.Response & result.Duration
}

private dynamic GetResponse()
{
    var stopwatch = Stopwatch.StartNew();
    var response = ...;
    stopwatch.Stop();
    return new
    {
        Response = response,
        Duration = stopwatch.Elapsed
    };
}

Same effect, less code!

Making a POST request in C# with Basic Authentication

Making a GET request using Basic Authentication is pretty easy using the BCL:

var webRequest = WebRequest.Create(uri);
webRequest.Credentials = new NetworkCredential("userName", "password");
using (var webResponse = webRequest.GetResponse())
{
    using (var responseStream = webResponse.GetResponseStream())
    {
        return new StreamReader(responseStream).ReadToEnd();
    }
}

As is making an unauthenticated POST request:

var webRequest = WebRequest.Create(uri);
webRequest.Method = "POST";
var bytes = Encoding.UTF8.GetBytes(data);
webRequest.ContentLength = bytes.Length;
webRequest.ContentType = "application/x-www-form-urlencoded";
using (var requestStream = webRequest.GetRequestStream())
{
	requestStream.Write(bytes, 0, bytes.Length);
}
...

But, for some reason, combining the two resulted in me being redirected to the login page. I thought it might need to be done in a specific order (like setting the content length before the type), but nothing I tried made any difference.

Luckily a StackOverflow post suggested an alternative, explicitly setting the Authorization header:

var webRequest = WebRequest.Create(uri);
webRequest.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(username + ":" + password));
webRequest.Method = "POST";
...

Which works as expected.

TransactionController

Transactions are a common cross-cutting concern, that need to be managed carefully.

You often want a transaction to be shared between multiple repositories, but you don’t want low level details (e.g. what ORM you are using) to bleed out of the persistence layer.

There’s also a lot of boiler plate code, and forgetting to commit the transaction is a common (and easy) mistake to make.

Bring the Func!

	public class TransactionController : ITransactionController
	{
		private readonly ISession _session;

		public TransactionController(ISession session)
		{
			_session = session;
		}

		public void InTransaction(Action action)
		{
			using (var transaction = _session.BeginTransaction())
			{
				action();
				transaction.Commit();
			}
		}
	}

	[TestFixture]
	public class TransactionControllerTests
	{
		private TransactionController _transactionController;
		private ISession _session;

		[SetUp]
		public void SetUp()
		{
			_session = MockRepository.GenerateStub<ISession>();
			_transactionController = new TransactionController(_session);
		}

		[Test]
		public void Begin_transaction()
		{
			StubTransaction();

			_transactionController.InTransaction(() => { });

			_session.AssertWasCalled(s => s.BeginTransaction());
		}

		[Test]
		public void Perform_action()
		{
			StubTransaction();
			var flag = false;

			_transactionController.InTransaction(() => { flag = true; });

			Assert.That(flag, Is.True);
		}

		[Test]
		public void Commit_transaction()
		{
			var transaction = StubTransaction();

			_transactionController.InTransaction(() => { });

			transaction.AssertWasCalled(t => t.Commit());
		}

		[Test]
		public void Dispose_transaction()
		{
			var transaction = StubTransaction();

			_transactionController.InTransaction(() => { });

			transaction.AssertWasCalled(t => t.Dispose());
		}

		[Test]
		public void Rollback_on_error()
		{
			var transaction = StubTransaction();

			try
			{
				_transactionController.InTransaction(() => { throw new Exception(); });
			}
			catch (Exception)
			{ }

			transaction.AssertWasNotCalled(t => t.Commit());
			transaction.AssertWasCalled(t => t.Dispose());
		}

		private ITransaction StubTransaction()
		{
			var transaction = MockRepository.GenerateStub<ITransaction>();
			_session.Stub(s => s.BeginTransaction()).Return(transaction);
			return transaction;
		}
	}

This can also be done using an AOP framework (like PostSharp) but, having tried that, I prefer it to be explicit in the code.