Skip to content

Instantly share code, notes, and snippets.

@mikehadlow
Last active December 16, 2019 09:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mikehadlow/474172cbf6452bce91e3 to your computer and use it in GitHub Desktop.
Save mikehadlow/474172cbf6452bce91e3 to your computer and use it in GitHub Desktop.
C#: Only Use Static Methods
public class Thing : IThing
{
public Thing(IDependency dependency) { }
public void Do(string arg) { }
}
public static void DoThing(IDependency dependency, string arg) { }
public static Action Compose()
{
return () => RunCustomerReportBatch(
GetCustomersForCustomerReport,
CreateCustomerReport,
SendEmail);
}
[Fact]
public void FunctionalTest()
{
// arrange
var expectedCustomer = new Customer("fist@sea.com");
var expectedReportBody = "the report body";
Func<IEnumerable<Customer>> getCustomersForCustomerReport =
() => new[] {expectedCustomer};
Func<Customer, Report> createCustomerReport =
customer => new Report(expectedCustomer.Email, expectedReportBody);
var actualToAddress = "";
var actualBody = "";
Action<string, string> sendEmail = (toAddress, body) =>
{
actualToAddress = toAddress;
actualBody = body;
};
// act
Functional.RunCustomerReportBatch(getCustomersForCustomerReport, createCustomerReport, sendEmail);
// assert
Assert.Equal(expectedCustomer.Email, actualToAddress);
Assert.Equal(expectedReportBody, actualBody);
}
public class CustomerData : ICustomerData
{
public IEnumerable<Customer> GetCustomersForCustomerReport()
{
// pretend to do data access
yield return new Customer("mike@mikelair.com");
yield return new Customer("leo@leofort.com");
yield return new Customer("yuna@yunacastle.com");
}
}
public class ReportBuilder : IReportBuilder
{
public Report CreateCustomerReport(Customer customer)
{
return new Report(customer.Email, $"This is the report for {customer.Email}!");
}
}
public class Emailer : IEmailer
{
public void Send(string toAddress, string body)
{
// pretend to send an email here
Console.Out.WriteLine("Sent Email to: {0}, Body: '{1}'", toAddress, body);
}
}
public interface ICustomerData
{
IEnumerable<Customer> GetCustomersForCustomerReport();
}
public interface IReportBuilder
{
Report CreateCustomerReport(Customer customer);
}
public interface IEmailer
{
void Send(string toAddress, string body);
}
public static ReportingService Compose()
{
return new ReportingService(
new CustomerData(),
new ReportBuilder(),
new Emailer()
);
}
[Fact]
public void RunCustomerReportBatchShouldSendReports()
{
// Arrange
var customerDataMock = new Mock<ICustomerData>();
var reportBuilderMock = new Mock<IReportBuilder>();
var emailerMock = new Mock<IEmailer>();
var expectedCustomer = new Customer("fist@sea.com");
var expectedReportBody = "the report body";
customerDataMock.Setup(x => x.GetCustomersForCustomerReport())
.Returns(new[] { expectedCustomer });
reportBuilderMock.Setup(x => x.CreateCustomerReport(expectedCustomer))
.Returns(new Report(expectedCustomer.Email, expectedReportBody));
var sut = new ReportingService(
customerDataMock.Object,
reportBuilderMock.Object,
emailerMock.Object);
// Act
sut.RunCustomerReportBatch();
// Assert
emailerMock.Verify(x => x.Send(expectedCustomer.Email, expectedReportBody));
}
public class ReportingService
{
public ReportingService(ICustomerData customerData, IReportBuilder reportBuilder, IEmailer emailer)
{
CustomerData = customerData;
ReportBuilder = reportBuilder;
Emailer = emailer;
}
public ICustomerData CustomerData { get; private set; }
public IReportBuilder ReportBuilder { get; private set; }
public IEmailer Emailer { get; private set; }
public void RunCustomerReportBatch()
{
var customers = CustomerData.GetCustomersForCustomerReport();
foreach (var customer in customers)
{
var report = ReportBuilder.CreateCustomerReport(customer);
Emailer.Send(report.ToAddress, report.Body);
}
}
}
public static void RunCustomerReportBatch(
Func<IEnumerable<Customer>> getCustomersForCustomerReport,
Func<Customer, Report> createCustomerReport,
Action<string, string> sendEmail)
{
var customers = getCustomersForCustomerReport();
foreach (var customer in customers)
{
var report = createCustomerReport(customer);
sendEmail(report.ToAddress, report.Body);
}
}
public static IEnumerable<Customer> GetCustomersForCustomerReport()
{
// pretend to do data access
yield return new Customer("mike@mikelair.com");
yield return new Customer("leo@leofort.com");
yield return new Customer("yuna@yunacastle.com");
}
public static Report CreateCustomerReport(Customer customer)
{
return new Report(customer.Email, $"This is the report for {customer.Email}!");
}
public static void SendEmail(string toAddress, string body)
{
// pretend to send an email here
Console.Out.WriteLine("Sent Email to: {0}, Body: '{1}'", toAddress, body);
}
var dependency = new ThingThatImplementsIDependency();
// RelyOnThing is something that that takes Action<string> as a dependency.
Action relyOnThing = () => RelyOnThing(arg => DoThing(dependency, arg));
@nverinaud
Copy link

Hi, line 3 of ThingComposition.csx contains a small typo: that that. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment