main
1namespace domain
2{
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6 using utility;
7
8 public interface IWell
9 {
10 IQuantity GrossProductionFor<Commodity>(Month month) where Commodity : ICommodity, new();
11 IQuantity NetProductionFor<Commodity>(Month month) where Commodity : ICommodity, new();
12 void FlowInto(IFacility facility);
13 }
14
15 public class Well : IWell
16 {
17 Month initialProductionMonth;
18 Percent workingInterest;
19 TypeCurve curve;
20 IFacility facility;
21
22 public Well(Month initialProductionMonth, Percent workingInterest, TypeCurve curve)
23 {
24 this.initialProductionMonth = initialProductionMonth;
25 this.workingInterest = workingInterest;
26 this.curve = curve;
27 }
28
29 public IQuantity GrossProductionFor<Commodity>(Month month) where Commodity : ICommodity, new()
30 {
31 return curve.ProductionFor<Commodity>(month);
32 }
33
34 public IQuantity NetProductionFor<Commodity>(Month month) where Commodity : ICommodity, new()
35 {
36 return workingInterest.Reduce(GrossProductionFor<Commodity>(month));
37 }
38
39 public void FlowInto(IFacility facility)
40 {
41 ensure_that_this_well_is_not_already_flowing_into_a_plant();
42 ensure_that_this_well_does_not_overflow_the_plant(facility);
43 facility.AcceptFlowFrom(this);
44 this.facility = facility;
45 }
46
47 void ensure_that_this_well_does_not_overflow_the_plant(IFacility facility)
48 {
49 var period = initialProductionMonth.UpTo(Month.Infinity);
50 this.curve.Accept( production =>
51 {
52 if( production.OccursDuring(period) && production.IsGreaterThanAvailableAt(facility))
53 throw new Exception();
54 });
55 }
56
57 void ensure_that_this_well_is_not_already_flowing_into_a_plant()
58 {
59 if(null != this.facility) throw new Exception();
60 }
61 }
62}